{"record":{"id":"b18ca56b09f3145c","repo":"can1357/oh-my-pi","slug":"missing-value-for-flag","errorCode":null,"errorMessage":"missing value for ${flag}","messagePattern":"missing value for (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/metaharness/src/runner.ts","lineNumber":207,"sourceCode":"\nexport function parseArgs(argv: string[]): Config {\n\tconst cfg = defaultConfig();\n\tfor (let i = 0; i < argv.length; i++) {\n\t\tlet arg = argv[i];\n\t\tif (arg === \"--\") {\n\t\t\tcfg.passthrough.push(...argv.slice(i + 1));\n\t\t\tbreak;\n\t\t}\n\t\tlet inlineValue: string | null = null;\n\t\tconst eq = arg.startsWith(\"--\") ? arg.indexOf(\"=\") : -1;\n\t\tif (eq !== -1) {\n\t\t\tinlineValue = arg.slice(eq + 1);\n\t\t\targ = arg.slice(0, eq);\n\t\t}\n\t\tconst take = (flag: string): string => {\n\t\t\tif (inlineValue !== null) return inlineValue;\n\t\t\tconst v = argv[i + 1];\n\t\t\tif (v === undefined) throw new Error(`missing value for ${flag}`);\n\t\t\ti++;\n\t\t\treturn v;\n\t\t};\n\t\tswitch (arg) {\n\t\t\tcase \"-m\":\n\t\t\tcase \"--model\":\n\t\t\t\tcfg.models.push(take(arg));\n\t\t\t\tbreak;\n\t\t\tcase \"--agent\":\n\t\t\t\tcfg.agent = take(arg);\n\t\t\t\tbreak;\n\t\t\tcase \"--install\": {\n\t\t\t\tconst v = take(arg);\n\t\t\t\tif (v !== \"source\" && v !== \"local\" && v !== \"published\") {\n\t\t\t\t\tthrow new Error(\"--install must be source|local|published\");\n\t\t\t\t}\n\t\t\t\tcfg.install = v;\n\t\t\t\tbreak;","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/metaharness/src/runner.ts#L189-L225","documentation":"The metaharness runner's parseArgs defines a take() helper for flags that require a value (e.g. --model, --provider). If a flag needing a value is the last argv entry (or no next argv element exists) and no inline value was given via =, take throws this Error naming the flag.","triggerScenarios":"Invoking the runner with a trailing valueless flag: `runner -m`, `runner --model` with nothing after it, or `runner -p` at end of argv.","commonSituations":"Shell scripts building args conditionally so the value gets dropped (empty variable expansion); copy-pasted commands missing the value; wrappers that forward args but truncate the last one.","solutions":["Append the value after the flag: --model anthropic/claude-sonnet-4-6 or --model=anthropic/claude-sonnet-4-6.","Fix the calling script so variable expansions never drop the value (quote variables: \"${MODEL}\" and guard empties).","Check the exact flag named in the error message and supply its missing value.","Optionally pre-validate argv length in wrapper scripts before exec."],"exampleFix":"# before\nomp-runner --model   # missing value\n# after\nomp-runner --model anthropic/claude-sonnet-4-6","handlingStrategy":"validation","validationCode":"function assertArgsComplete(argv: string[], valueFlags: string[]): void {\n\tfor (let i = 0; i < argv.length; i++) {\n\t\tif (valueFlags.includes(argv[i]) && (i + 1 >= argv.length || argv[i + 1].startsWith(\"--\"))) {\n\t\t\tthrow new Error(`${argv[i]} requires a value`);\n\t\t}\n\t}\n}","typeGuard":null,"tryCatchPattern":"try {\n\trun(parseArgs(process.argv.slice(2)));\n} catch (err) {\n\tif (err instanceof Error && err.message.startsWith(\"missing value for\")) {\n\t\tconsole.error(`${err.message}\\nusage: runner --model <provider/model> ...`);\n\t\tprocess.exit(2);\n\t}\n\tthrow err;\n}","preventionTips":["Quote shell variables so values are never dropped: --model \"${MODEL}\".","Guard empty env-derived values before building the argv array.","Prefer --flag=value form to make missing values visible.","Test wrapper scripts with the flag last to catch truncation."],"tags":["cli","arguments","parsing"],"backgroundTag":"missing-cli-argument","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}