{"record":{"id":"64a1311a5de83279","repo":"perspective-dev/perspective","slug":"pkg-info-value-for-field-name-was-not-a-string","errorCode":null,"errorMessage":"PKG-INFO value for field ${name} was not a string:\\n${value}","messagePattern":"PKG-INFO value for field (.+?) was not a string:\\\\n(.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"rust/perspective-python/build.mjs","lineNumber":184,"sourceCode":"if (process.env[\"PSP_UV\"] === \"1\") {\n    flags += \" --uv\";\n}\n\nif (!build_wheel && !build_sdist) {\n    const dev_features = [\"abi3\"];\n    execSync(\n        `${emsdk_prefix}maturin develop --features=${dev_features.join(\",\")} ${flags} ${target}`,\n        { stdio: \"inherit\", env },\n    );\n}\n\n// Generates version 2.3 according to https://packaging.python.org/en/latest/specifications/core-metadata/\n// Takes parsed pyproject.toml, Cargo.toml, and contents of README.md.\nfunction generatePkgInfo(pyproject, cargo, readme_md) {\n    const project = pyproject[\"project\"];\n    const field = (name, value) => {\n        if (typeof value !== \"string\") {\n            throw new Error(\n                `PKG-INFO value for field ${name} was not a string:\\n${value}`,\n            );\n        }\n        return `${name}: ${value}`;\n    };\n    const lines = [];\n    const addField = (key, value) => lines.push(field(key, value));\n    addField(\"Metadata-Version\", \"2.3\");\n    addField(\"Name\", project.name);\n    addField(\"Version\", cargo.package.version);\n    for (const c of project[\"classifiers\"]) {\n        addField(\"Classifier\", c);\n    }\n    for (const [extra, deps] of Object.entries(\n        project[\"optional-dependencies\"],\n    )) {\n        for (const dep of deps) {\n            addField(\"Requires-Dist\", `${dep} ; extra == '${extra}'`);","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/perspective-dev/perspective/blob/11c8238c0c9c0b9e490b5a6a2dc277afad1e980a/rust/perspective-python/build.mjs#L166-L202","documentation":"generatePkgInfo builds the wheel's PKG-INFO (core metadata spec 2.3) from pyproject.toml, Cargo.toml, and README.md. Its internal `field` helper throws when a metadata value is not a string, because a non-string cannot be rendered as a `Name: value` header line. This indicates a malformed or unexpectedly typed field (often a version read from Cargo.toml as a non-string, or a list/dict where a string was expected).","triggerScenarios":"Calling generatePkgInfo (via the build script) when any metadata field passed to `field(name, value)` is not typeof 'string' — e.g. pyproject `project.version` missing so a number/object is substituted, or a list field (like authors/classifiers) passed as a single-string field.","commonSituations":"Hand-edited pyproject.toml with a numeric version (e.g. version = 1.2 not \"1.2\"); Cargo.toml version parsed as a non-string; a required metadata field resolving to undefined/object after merging sources.","solutions":["Inspect the pyproject.toml/Cargo.toml field named in the error and make sure its value is a quoted string (e.g. version = \"1.2.3\", not 1.2.3)","Check generatePkgInfo's source assembly to see which source (pyproject, cargo, readme) supplies that field and fix the extraction if it yields a non-string","Add a pre-build validation that all PKG-INFO fields are strings, or coerce/serialize lists explicitly before calling field()"],"exampleFix":"# before (pyproject.toml)\n[project]\nversion = 1\n// after\n[project]\nversion = \"1.0.0\"","handlingStrategy":"validation","validationCode":"const pyproject = require('./pyproject.toml');\nfor (const [k, v] of Object.entries(pyproject.project)) {\n  if (typeof v === 'number' || typeof v === 'undefined') throw new Error(`Metadata field ${k} must be a string`);\n}","typeGuard":"const isStr = (v) => typeof v === 'string';\nif (!isStr(pyproject.project.version)) throw new Error('project.version must be a quoted string');","tryCatchPattern":"try { generatePkgInfo(pyproject, cargo, readme); } catch (e) { const m = e.message.match(/field (\\w+) was not a string/); console.error(`Fix metadata field \"${m?.[1]}\" in pyproject.toml / Cargo.toml — it must be a string`); throw e; }","preventionTips":["Always quote version and other scalar metadata values in pyproject.toml","Validate metadata types before running builds","After editing Cargo.toml/pyproject.toml, rebuild from clean state to catch type regressions early"],"tags":["build","metadata","type-error"],"backgroundTag":"type-mismatch","analyzedSha":"11c8238c0c9c0b9e490b5a6a2dc277afad1e980a","analyzedAt":"2026-09-09T00:35:19.377Z","contentChangedAt":"2026-09-09T00:35:19.377Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}