Incorrect Dynamic Property Access in Package Data Resolver
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 75/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- typescript
- Domain
- backend-api-design
Research direction
The issue is in scopes/dependencies/dependencies/resolve-pkg-data.ts lines 66-74. Look at the enrichDataFromDependent function. The fix is to change .packageName to [packageName] in three places. Run the existing tests in resolve-pkg-data.spec.ts to verify the change works. The test case described can be added to ensure the versionUsedByDependent is correctly populated from dependencies, devDependencies, or peerDependencies.
Written by the indexing model from the issue text.
Description
Issue : Incorrect Dynamic Property Access in Package Data Resolver
Metadata
- Subsystem:
scopes/dependencies/dependencies - Source File:
scopes/dependencies/dependencies/resolve-pkg-data.ts - Line Numbers: 66–74
- Severity:
High - Keywords:
dependency-resolution,package.json,version-ranges,property-access
Problem Description
In scopes/dependencies/dependencies/resolve-pkg-data.ts, the function enrichDataFromDependent() resolves package information from a dependent component's package.json. It attempts to look up the package version or semver range defined in dependencies, devDependencies, or peerDependencies.
Instead of utilizing computed property bracket notation ([packageName]), the code uses dot notation with the literal identifier (.packageName).
Vulnerable Code
// scopes/dependencies/dependencies/resolve-pkg-data.ts: Lines 65-75
const packageName = resolvePackageNameByPath(packageRelativePath);
const packageVersion =
dependentPackageJson.dependencies?.packageName ||
dependentPackageJson.devDependencies?.packageName ||
dependentPackageJson.peerDependencies?.packageName;
if (packageVersion) {
packageData.dependentPackageJsonPath = packageJsonInfo.path;
packageData.name = packageName;
packageData.versionUsedByDependent = packageVersion;
}
Root Cause Analysis
packageNameis a variable holding the resolved package string (e.g.'lodash','chalk', or'@teambit/base-ui').dependentPackageJson.dependencies?.packageNamechecks for the literal key"packageName"inside the dependencies map:{ "dependencies": { "packageName": "1.0.0" } }- Unless a project literally depends on a package titled
"packageName",packageVersionstrictly evaluates toundefined. - As a result, the condition
if (packageVersion)at line 70 is never entered for any standard package.
Real-World Impact
According to the file's architectural documentation (lines 20–29):
"for a package that is not bit-component, we're interested in the range because that's how it was set in the first place and changing it to an exact version result in the component modified."
Because versionUsedByDependent is never populated from dependentPackageJson, Bit loses the author's specified semver range (e.g., ^1.2.0 or ~2.0.0). Bit falls back to reading concreteVersion from the package's internal package.json in node_modules (e.g., 1.2.4). This can lead to:
- Bit marking components as modified unexpectedly due to forced exact version pinning.
- Inability to retain and propagate semver ranges when snapping or tagging components.
Proposed Fix
Replace static dot notation .packageName with dynamic bracket notation [packageName]:
--- a/scopes/dependencies/dependencies/resolve-pkg-data.ts
+++ b/scopes/dependencies/dependencies/resolve-pkg-data.ts
@@ -64,9 +64,9 @@ function enrichDataFromDependent(packageData: ResolvedPackageData, dependentDir:
const packageName = resolvePackageNameByPath(packageRelativePath);
const packageVersion =
- dependentPackageJson.dependencies?.packageName ||
- dependentPackageJson.devDependencies?.packageName ||
- dependentPackageJson.peerDependencies?.packageName;
+ dependentPackageJson.dependencies?.[packageName] ||
+ dependentPackageJson.devDependencies?.[packageName] ||
+ dependentPackageJson.peerDependencies?.[packageName];
if (packageVersion) {
packageData.dependentPackageJsonPath = packageJsonInfo.path;
packageData.name = packageName;
Verification & Unit Test
Add a test in resolve-pkg-data.spec.ts:
it('should populate versionUsedByDependent from dependent package.json dependencies', () => {
const result = resolvePackageData(dependentFixtureDir, packageFullPath);
expect(result).to.not.be.undefined;
expect(result?.name).to.equal('lodash');
expect(result?.versionUsedByDependent).to.equal('^4.17.21');
});
- Dominant language
- TypeScript
- Stars
- 18.5k
- Forks
- 962
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 119
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from teambit/bit
-
Difficulty 1/5 Under an hour Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
type/bug
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
Maintainers usually reply within 1 day
-
merge-queue
Difficulty 5/5 Over a week Newbie friendliness 15/100
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 48/100
Maintainers usually reply within 1 day
-
cross-copy instanceof checks on error classes break when capsules host multiple copies of a packageOpen
Difficulty 4/5 3-5 days Newbie friendliness 52/100
Maintainers usually reply within 1 day
Similar issues
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Difficulty 1/5 Under an hour Newbie friendliness 83/100
lingdojo/kana-dojo#33701 · 1 comment · 5 reactions ·
Maintainers usually reply within 1 day
-
tech-debt
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
rookslog/zlibrary-mcp#408 ·
Maintainers usually reply within 1 day
-
mp4box.js — 20-byte `sgpd` box with large `entry_count` causes unbounded loop and heap OOM abortOpen
Difficulty 2/5 1-3 hours Newbie friendliness 77/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
status: needs triage
Difficulty 2/5 1-3 hours Newbie friendliness 64/100
mastra-ai/mastra#29641 · 1 comment ·
Maintainers usually reply within 1 day