{"record":{"id":"6882aa561b110c4d","repo":"garrytan/gstack","slug":"pdf-from-file-payloadpath-must-be-a-json-obj","errorCode":null,"errorMessage":"pdf: --from-file ${payloadPath} must be a JSON object, got ${Array.isArray(json) ? 'array' : typeof json}.","messagePattern":"pdf: --from-file (.+?) must be a JSON object, got (.+?)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"browse/src/meta-commands.ts","lineNumber":161,"sourceCode":"  // must pass validateReadPath so the safe-dirs policy can't be skirted\n  // by routing reads through the --from-file shortcut.\n  try {\n    validateReadPath(path.resolve(payloadPath));\n  } catch {\n    throw new Error(\n      `pdf: --from-file ${payloadPath} must be under ${SAFE_DIRECTORIES.join(' or ')} (security policy). Copy the payload into the project tree or /tmp first.`\n    );\n  }\n  const raw = fs.readFileSync(payloadPath, 'utf8');\n  let json: any;\n  try {\n    json = JSON.parse(raw);\n  } catch (err) {\n    const msg = err instanceof Error ? err.message : String(err);\n    throw new Error(`pdf: --from-file ${payloadPath} is not valid JSON (${msg}).`);\n  }\n  if (json === null || typeof json !== 'object' || Array.isArray(json)) {\n    throw new Error(`pdf: --from-file ${payloadPath} must be a JSON object, got ${Array.isArray(json) ? 'array' : typeof json}.`);\n  }\n  const out: ParsedPdfArgs = {\n    output: json.output || `${TEMP_DIR}/browse-page.pdf`,\n    format: json.format,\n    width: json.width,\n    height: json.height,\n    marginTop: json.marginTop,\n    marginRight: json.marginRight,\n    marginBottom: json.marginBottom,\n    marginLeft: json.marginLeft,\n    headerTemplate: json.headerTemplate,\n    footerTemplate: json.footerTemplate,\n    pageNumbers: json.pageNumbers === true,\n    tagged: json.tagged === true,\n    outline: json.outline === true,\n    printBackground: json.printBackground === true,\n    preferCSSPageSize: json.preferCSSPageSize === true,\n    toc: json.toc === true,","sourceCodeStart":143,"sourceCodeEnd":179,"githubUrl":"https://github.com/garrytan/gstack/blob/94993f74012782fd94416dd44b8314f6363a13a4/browse/src/meta-commands.ts#L143-L179","documentation":"Thrown by parsePdfFromFile() when the parsed JSON is not a plain object — it is null, an array, or a primitive type (string, number, boolean). The PDF config must be a JSON object whose keys map to ParsedPdfArgs fields (output, format, width, etc.).","triggerScenarios":"The --from-file JSON file parses successfully but the top-level value is an array (e.g., '[...]'), null, or a primitive like a bare string or number.","commonSituations":"User wraps the config in an array instead of an object, or the file contains a bare JSON value from a different tool's output format.","solutions":["Ensure the JSON file's top-level value is an object ({...}), not an array ([...]) or primitive","Wrap any array content inside an object if the config needs list data"],"exampleFix":"// before — array at top level\n[\n  { \"format\": \"A4\" },\n  { \"format\": \"Letter\" }\n]\n\n// after — single object\n{\n  \"format\": \"A4\",\n  \"printBackground\": true\n}","handlingStrategy":"type-guard","validationCode":"const raw = fs.readFileSync(payloadPath, 'utf8');\nconst json = JSON.parse(raw);\nif (json === null || typeof json !== 'object' || Array.isArray(json)) {\n  throw new Error('Payload must be a JSON object');\n}","typeGuard":"function isPdfConfigObject(v: unknown): v is Record<string, unknown> {\n  return typeof v === 'object' && v !== null && !Array.isArray(v);\n}","tryCatchPattern":null,"preventionTips":["Ensure the JSON file's top-level value is {...}, not [...] or a primitive","Use a JSON schema validator to check structure before passing to --from-file"],"tags":["pdf","json","validation","type-mismatch"],"backgroundTag":null,"analyzedSha":"94993f74012782fd94416dd44b8314f6363a13a4","analyzedAt":"2026-08-12T04:06:23.140Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}