{"record":{"id":"9e5288cb5f357432","repo":"garrytan/gstack","slug":"pdf-from-file-requires-a-path","errorCode":null,"errorMessage":"pdf: --from-file requires a path","messagePattern":"pdf: --from-file requires a path","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"browse/src/meta-commands.ts","lineNumber":86,"sourceCode":"  marginRight?: string;\n  marginBottom?: string;\n  marginLeft?: string;\n  headerTemplate?: string;\n  footerTemplate?: string;\n  pageNumbers?: boolean;\n  tagged?: boolean;\n  outline?: boolean;\n  printBackground?: boolean;\n  preferCSSPageSize?: boolean;\n  toc?: boolean;\n}\n\nfunction parsePdfArgs(args: string[]): ParsedPdfArgs {\n  // --from-file short-circuits argv parsing entirely\n  for (let i = 0; i < args.length; i++) {\n    if (args[i] === '--from-file') {\n      const payloadPath = args[++i];\n      if (!payloadPath) throw new Error('pdf: --from-file requires a path');\n      return parsePdfFromFile(payloadPath);\n    }\n  }\n\n  const result: ParsedPdfArgs = {\n    output: `${TEMP_DIR}/browse-page.pdf`,\n  };\n\n  let margins: string | undefined;\n  const positional: string[] = [];\n\n  for (let i = 0; i < args.length; i++) {\n    const a = args[i];\n    if (a === '--format') { result.format = requireValue(args, ++i, 'format'); }\n    else if (a === '--page-size') { result.format = requireValue(args, ++i, 'page-size'); }\n    else if (a === '--width') { result.width = requireValue(args, ++i, 'width'); }\n    else if (a === '--height') { result.height = requireValue(args, ++i, 'height'); }\n    else if (a === '--margins') { margins = requireValue(args, ++i, 'margins'); }","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/garrytan/gstack/blob/94993f74012782fd94416dd44b8314f6363a13a4/browse/src/meta-commands.ts#L68-L104","documentation":"Thrown by parsePdfArgs() when the --from-file flag is present but is the last token in argv — the (++i) increment reads undefined. The --from-file flag short-circuits all other argv parsing and delegates to parsePdfFromFile, so it must be followed by a file path.","triggerScenarios":"Passing '--from-file' as the final argument to the pdf command with no subsequent path token.","commonSituations":"User forgets to specify the JSON payload path after --from-file, or a script constructs the command string and omits the path argument.","solutions":["Add the JSON file path immediately after --from-file","If building the command programmatically, ensure the path variable is non-empty before appending it"],"exampleFix":"# before\n$B pdf --from-file\n\n# after\n$B pdf --from-file /tmp/pdf-config.json","handlingStrategy":"validation","validationCode":"// Validate --from-file has a path before invoking\nconst idx = args.indexOf('--from-file');\nif (idx !== -1 && idx === args.length - 1) {\n  throw new Error('--from-file requires a path argument');\n}","typeGuard":null,"tryCatchPattern":"// Wrap CLI invocation in try-catch for user-facing error display\ntry {\n  await runPdfCommand(args);\n} catch (e) {\n  if (e.message.includes('--from-file requires a path')) {\n    showUsage('pdf --from-file <path>');\n  }\n}","preventionTips":["When building pdf command strings programmatically, assert the path variable is non-empty before appending --from-file","Provide a default path or fail early in the calling code if the config path is missing"],"tags":["pdf","cli","argument-parsing"],"backgroundTag":null,"analyzedSha":"94993f74012782fd94416dd44b8314f6363a13a4","analyzedAt":"2026-08-12T04:06:23.140Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}