{"record":{"id":"868f1fdab3766225","repo":"langgenius/dify","slug":"expected-integer-got-json-stringify-raw","errorCode":null,"errorMessage":"expected integer, got ${JSON.stringify(raw)}","messagePattern":"expected integer, got (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cli/src/framework/flags.ts","lineNumber":91,"sourceCode":"    Opts extends { default: number } ? number : number | undefined\n  >\n}\n\nfunction stringArg<const Opts extends { description: string; required?: boolean }>(\n  opts: Opts,\n): ArgDefinition<Opts extends { required: true } ? string : string | undefined> {\n  return opts as ArgDefinition<Opts extends { required: true } ? string : string | undefined>\n}\n\nexport const Args = {\n  string: stringArg,\n}\n\nfunction coerceFlagValue(raw: string, def: FlagDefinition): string | boolean | number {\n  switch (def.type) {\n    case 'integer': {\n      const n = Number(raw)\n      if (Number.isNaN(n)) throw new Error(`expected integer, got ${JSON.stringify(raw)}`)\n\n      return n\n    }\n    case 'boolean': {\n      if (raw === 'true' || raw === '1') return true\n\n      if (raw === 'false' || raw === '0') return false\n\n      throw new Error(`expected boolean, got ${JSON.stringify(raw)}`)\n    }\n    default:\n      return raw\n  }\n}\n\nfunction accumulateFlagValue(\n  flags: ParsedFlags,\n  name: string,","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/langgenius/dify/blob/ef8544b173fd6cd7a8e71df2cab576e52bebbfbc/cli/src/framework/flags.ts#L73-L109","documentation":"A bare Error thrown by coerceFlagValue (flags.ts:91) when a flag declared with Flags.integer(...) receives a value that Number() turns into NaN. NOTE the check is only `Number.isNaN(n)` — values like '1.5', '0x10', '1e3', 'Infinity', and '' are NOT caught here because Number() parses them; only non-numeric strings throw. Also it is a plain Error (not BaseError), so it bypasses the structured error/exit-code mapping and surfaces as a generic failure.","triggerScenarios":"Passing a non-numeric token to an integer flag: `--limit=abc`, `--page foo` where foo is text, `--retry=`. The case-insensitive Number() coercion means 'NaN' literally, 'undefined', or arbitrary identifiers trip it. Floats, scientific notation, and hex slip through silently (a latent correctness bug).","commonSituations":"Typos in flag values; copy-pasting a value with units (`--limit=10x`); env-driven scripts interpolating an unset variable (`--page=$PAGE` where PAGE is empty or non-numeric); confusing a string flag for an integer one; shell glob expanding to a non-numeric value.","solutions":["Supply a base-10 integer: `--limit=50`.","Quote/validate the value in your shell before passing it: `[[ \"$LIMIT\" =~ ^[0-9]+$ ]] && difyctl ... --limit=\"$LIMIT\"`.","Check the command's --help to confirm the flag is integer-typed and which name is expected.","If maintaining difyctl: tighten coerceFlagValue to reject non-integers (e.g., !Number.isInteger(n) or a strict /^[+-]?\\d+$/ regex) and wrap as a BaseError so the exit code is Usage (2) not Generic (1)."],"exampleFix":"// before — non-numeric trips NaN\ndifyctl apps list --limit=abc\n\n// after\ndifyctl apps list --limit=50\n\n// hardening suggestion for cli/src/framework/flags.ts (integer case)\ncase 'integer': {\n  if (!/^[-+]?\\d+$/.test(raw.trim()))\n    throw new BaseError({ code: ErrorCode.UsageInvalidFlag, message: `expected integer, got ${JSON.stringify(raw)}` })\n  return Number(raw)\n}","handlingStrategy":"validation","validationCode":"// validate integer flag values before they reach parseArgv\nfunction asInteger(raw: string, flag: string): number {\n  if (!/^[+-]?\\d+$/.test(raw.trim())) {\n    throw new Error(`--${flag} expects a base-10 integer, got ${JSON.stringify(raw)}`)\n  }\n  return Number(raw)\n}\n// usage: asInteger(process.env.LIMIT ?? '', 'limit')","typeGuard":"function isIntegerString(v: string): boolean {\n  return /^[+-]?\\d+$/.test(v.trim())\n}","tryCatchPattern":null,"preventionTips":["Validate integer flag inputs in your wrapper script with a regex before passing to difyctl.","Beware Number() quirks: it accepts '0x10', '1e3', '1.5', '' as 0 — use a strict integer regex.","When extending difyctl, wrap coerceFlagValue throws in BaseError(UsageInvalidFlag) for exit code 2."],"tags":["cli","flags","parsing","integer","validation"],"backgroundTag":null,"analyzedSha":"ef8544b173fd6cd7a8e71df2cab576e52bebbfbc","analyzedAt":"2026-08-12T05:15:17.394Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}