{"record":{"id":"10c3bad8eee9752c","repo":"unslothai/unsloth","slug":"cell-uses-shell-metacharacters-interpolation-but","errorCode":null,"errorMessage":"Cell uses shell metacharacters / interpolation but --no-allow-shell was set; refusing to emit shell=True","messagePattern":"Cell uses shell metacharacters / interpolation but --no-allow-shell was set; refusing to emit shell=True","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"warning","filePath":"scripts/notebook_to_python.py","lineNumber":105,"sourceCode":"\n\ndef _emit_shell_command(indent: str, full_cmd: str, *, allow_shell: bool) -> list[str]:\n    \"\"\"Render a `!cmd` notebook line as Python statements.\n\n    f-string interpolation, shell metacharacters, or multiline force\n    shell=True (shlex.split would drop operators), flagged with a\n    WARNING comment. Otherwise emit shell=False argv form. allow_shell\n    False makes shell=True emission a hard error.\n    \"\"\"\n    needs_f = needs_fstring(full_cmd)\n    has_meta = bool(_SHELL_METACHARS_RE.search(full_cmd))\n    multiline = \"\\n\" in full_cmd\n\n    must_use_shell = needs_f or has_meta or multiline\n\n    if must_use_shell:\n        if not allow_shell:\n            raise ValueError(\n                \"Cell uses shell metacharacters / interpolation but \"\n                \"--no-allow-shell was set; refusing to emit shell=True\"\n            )\n        warn = f\"{indent}# WARNING: shell=True; reviewed for hostile input\"\n        f_prefix = \"f\" if needs_f else \"\"\n        if multiline:\n            escaped_cmd = full_cmd.replace('\"\"\"', r\"\\\"\\\"\\\"\")\n            if escaped_cmd.rstrip().endswith('\"'):\n                escaped_cmd = escaped_cmd.rstrip() + \" \"\n            stmt = f'{indent}subprocess.run({f_prefix}\"\"\"{escaped_cmd}\"\"\", shell=True)'\n        else:\n            stmt = f\"{indent}subprocess.run({f_prefix}{full_cmd!r}, shell=True)\"\n        return [warn, stmt]\n\n    return [f\"{indent}subprocess.run(shlex.split({full_cmd!r}), shell=False)\"]\n\n\ndef convert_cell_to_python(source: str, *, allow_shell: bool = True) -> str:","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/scripts/notebook_to_python.py#L87-L123","documentation":"Thrown by parseMaxOutputTokens (chat-providers-dialog.tsx:493-509) when the Max Tokens field is non-empty but fails /^\\d+$/ — i.e. it contains anything other than plain digits. Only an empty field returns null (no override); any other content must be a non-negative integer in decimal digits, so signs, decimals, thousands separators, and exponent notation are all rejected.","triggerScenarios":"Typing '1,024' (comma), '4.5', '-1', '1e5', '4096 ', or 'max' into the Max Tokens limit field of the custom provider dialog and submitting. The regex test at chat-providers-dialog.tsx:496 is the sole trigger.","commonSituations":"Users formatting numbers with locale separators; pasting values from docs that include units ('4096 tokens'); negative or float experiments; autocomplete inserting stray characters.","solutions":["Enter plain digits only, e.g. '4096'.","Remove commas, decimals, units, and whitespace.","Leave the field empty entirely if you don't want a per-provider token override — empty is valid."],"exampleFix":"// before\n1,024\n\n// after\n1024","handlingStrategy":"validation","validationCode":"function isDigitsOnly(input: string): boolean {\n  const t = input.trim();\n  return t === '' || /^\\d+$/.test(t);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set inputMode='numeric' and strip non-digits on change.","Strip locale separators (commas/spaces) automatically on paste.","Treat empty as 'no override' and communicate that in the field's placeholder."],"tags":["validation","form","providers","frontend","numbers"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}