{"record":{"id":"b398ef1bcd63007c","repo":"can1357/oh-my-pi","slug":"name-must-be-a-positive-integer","errorCode":null,"errorMessage":"--${name} must be a positive integer","messagePattern":"--(.+?) must be a positive integer","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/cli/dry-balance-cli.ts","lineNumber":201,"sourceCode":"}\n\ntype DryBalanceBenchTarget =\n\t| {\n\t\t\tok: true;\n\t\t\taccount: string;\n\t\t\taccessToken: string;\n\t\t\tcredentialId?: number;\n\t  }\n\t| {\n\t\t\tok: false;\n\t\t\taccount: string;\n\t\t\terror: string;\n\t  };\n\nfunction normalizePositiveInteger(name: string, value: number | undefined, fallback: number): number {\n\tconst resolved = value ?? fallback;\n\tif (!Number.isInteger(resolved) || resolved <= 0) {\n\t\tthrow new Error(`--${name} must be a positive integer`);\n\t}\n\treturn resolved;\n}\n\nfunction getErrorMessage(error: unknown): string {\n\tif (error instanceof Error && error.message) return error.message;\n\tconst message = String(error);\n\treturn message ? message : \"Unknown error\";\n}\n\nfunction extractAccount(access: {\n\temail?: string;\n\taccountId?: string;\n\tprojectId?: string;\n\tenterpriseUrl?: string;\n\torgId?: string;\n\torgName?: string;\n}): string {","sourceCodeStart":183,"sourceCodeEnd":219,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/cli/dry-balance-cli.ts#L183-L219","documentation":"normalizePositiveInteger validates the --samples and --concurrency flags of the `omp dry-balance` command. A value is rejected unless it is an integer strictly greater than zero. The flag name is interpolated into the message so you know which flag was bad.","triggerScenarios":"Running dry-balance with `--samples 0`, `--samples -3`, `--samples 2.5`, or a non-numeric string that the flag parser coerced to NaN/undefined-outside-fallback. Only flags explicitly passed (or non-positive fallbacks) reach this check.","commonSituations":"Typing `--samples 0` expecting 'unlimited' or 'auto'; passing a float like `--concurrency 1.5`; shell variable interpolation producing an empty or negative value; copy-pasting a locale-formatted number like `1,000`.","solutions":["Pass a whole number >= 1: --samples 10 --concurrency 4","Omit the flag entirely to use the built-in fallback instead of passing 0","Check the interpolated flag name in the message and fix that specific --flag","Quote numeric shell variables: --samples \"$N\" and confirm $N is a positive integer (echo \"$N\")"],"exampleFix":"// before\nomp dry-balance --samples 0\n// after\nomp dry-balance --samples 10 --concurrency 4","handlingStrategy":"validation","validationCode":"function assertPositiveInt(name, v) {\n  if (v !== undefined && (!Number.isInteger(v) || v <= 0))\n    throw new Error(`--${name} must be a positive integer`);\n}\nassertPositiveInt('samples', samples); assertPositiveInt('concurrency', concurrency);","typeGuard":"const isPositiveInt = (v: unknown): v is number =>\n  typeof v === 'number' && Number.isInteger(v) && v > 0;","tryCatchPattern":"try {\n  await runDryBalance({ samples, concurrency });\n} catch (e) {\n  if (/must be a positive integer/.test((e as Error).message)) {\n    console.error('Pass whole numbers >= 1, e.g. --samples 10 --concurrency 4');\n  } else throw e;\n}","preventionTips":["Never pass 0 expecting 'auto' — omit the flag to use fallbacks","Avoid floats and locale-formatted numbers (1,000); use plain integers","Quote shell variables feeding these flags and verify they are numeric"],"tags":["cli","argument-validation","dry-balance"],"backgroundTag":"invalid-flag-value","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}