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

  1. Open <packageDirectory>/package.json and fix the JSON syntax error reported by the wrapped message (line/column are included by encoding/json)
  2. Validate the file with 'node -e "JSON.parse(require(\"fs\").readFileSync(\"package.json\"))"' or 'npx jsonlint package.json'
  3. If the file was edited by hand, regenerate it with 'npm init' or the tooling that originally produced it
  4. 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

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


AI-assisted analysis of pulumi/pulumi@793f7b2e16 (2026-08-31). Data as JSON: /api/errors/67cf6f2d0b50e8a6. Report an issue: GitHub.