pulumi/pulumi · error
unmarshal package.json: %w
Error message
unmarshal package.json: %w
What it means
The Node.js language host reads package.json from the package directory and unmarshals it with json.Unmarshal in readPackageJSON (sdk/nodejs/cmd/pulumi-language-nodejs/main.go:1974). If the file exists but is not valid JSON (or is not a JSON object), the host wraps the unmarshal error with "unmarshal package.json: %w" and fails the Pack call.
Source
Thrown at sdk/nodejs/cmd/pulumi-language-nodejs/main.go:1974
if err != nil {
return nil, fmt.Errorf("could not write output file %s: %w", filename, err)
}
}
return &pulumirpc.GeneratePackageResponse{
Diagnostics: rpcDiagnostics,
}, nil
}
func readPackageJSON(packageJSONPath string) (map[string]any, error) {
packageJSONData, err := os.ReadFile(packageJSONPath)
if err != nil {
return nil, fmt.Errorf("read package.json: %w", err)
}
var packageJSON map[string]any
err = json.Unmarshal(packageJSONData, &packageJSON)
if err != nil {
return nil, fmt.Errorf("unmarshal package.json: %w", err)
}
return packageJSON, nil
}
func (host *nodeLanguageHost) Pack(ctx context.Context, req *pulumirpc.PackRequest) (*pulumirpc.PackResponse, error) {
// Verify npm exists and is set up: npm, user login
npm, err := executable.FindExecutable("npm")
if err != nil {
return nil, fmt.Errorf("find npm: %w", err)
}
// Annoyingly the engine will call Pack for the core SDK which is not setup in at all the same way as the
// generated sdks, so we have to detect that and do a big branch to pack it totally differently.
packageJSON, err := readPackageJSON(filepath.Join(req.PackageDirectory, "package.json"))
if err != nil {
return nil, err
}
View on GitHub (pinned to 793f7b2e16)
Solutions
- Open <packageDirectory>/package.json and fix the JSON syntax error reported by the wrapped message (line/column are included by encoding/json)
- Validate the file with 'node -e "JSON.parse(require(\"fs\").readFileSync(\"package.json\"))"' or 'npx jsonlint package.json'
- If the file was edited by hand, regenerate it with 'npm init' or the tooling that originally produced it
- Re-run the pulumi pack/pack-sdk command from a clean checkout
Example fix
// before (package.json)
{
"name": "my-provider",
"version": "1.0.0", // trailing comment
}
// after
{
"name": "my-provider",
"version": "1.0.0"
} Defensive patterns
Strategy: validation
Validate before calling
const fs = require('fs');
if (!fs.existsSync('package.json')) throw new Error('package.json missing');
JSON.parse(fs.readFileSync('package.json', 'utf8')); // throws with position if invalid Type guard
function isValidPackageJSON(raw) {
try {
const parsed = JSON.parse(raw);
return typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed);
} catch { return false; }
} Try / catch
try {
JSON.parse(fs.readFileSync('package.json', 'utf8'));
} catch (err) {
console.error('package.json is not valid JSON:', err.message);
process.exit(1);
} Prevention
- Run a JSON linter on package.json in pre-commit hooks
- Never hand-edit package.json while merge conflicts are unresolved
- Use npm/node tooling to modify package.json instead of manual edits
- Add 'node -e "JSON.parse(...)"' as a CI sanity check
When it happens
Trigger: Pulumi calls Pack on a package whose <PackageDirectory>/package.json exists but fails JSON parsing: truncated file, comments or trailing commas, BOM, invalid escape sequences, or a top-level JSON array/number/string instead of an object.
Common situations: Hand-edited package.json left syntactically invalid; a merge conflict marker committed into package.json; a file generated by a tool that wrote partial output; CI building a corrupted checkout.
Related errors
- could not parse --json argument: %w
- failed to parse schema: %w
- unmarshaling package.json %s: %w
- missing expected "name" property
- Missing property "name" for the third-party plugin '%v' insi
AI-assisted analysis of pulumi/pulumi@793f7b2e16 (2026-08-31).
Data as JSON: /api/errors/67cf6f2d0b50e8a6.
Report an issue: GitHub.