{"record":{"id":"64f4fa855b5923e0","repo":"bazelbuild/bazel","slug":"cannot-infer-base-when-string-begins-with-a-0-s","errorCode":null,"errorMessage":"cannot infer base when string begins with a 0: %s","messagePattern":"cannot infer base when string begins with a 0: (.+?)","errorType":"exception","errorClass":"NumberFormatException","httpStatus":null,"severity":"error","filePath":"src/main/java/net/starlark/java/eval/StarlarkInt.java","lineNumber":146,"sourceCode":"        prefixBase = 2;\n      } else if (c == 'o' || c == 'O') {\n        prefixBase = 8;\n      } else if (c == 'x' || c == 'X') {\n        prefixBase = 16;\n      }\n      if (prefixBase != 0) {\n        if (base == 0 || base == prefixBase) {\n          base = prefixBase;\n          digits = s.substring(2); // strip prefix\n        }\n      }\n    }\n\n    // No prefix, no base? Use decimal.\n    if (digits == s && base == 0) {\n      // Don't infer base when input starts with '0' due to octal/decimal ambiguity.\n      if (s.length() > 1 && s.charAt(0) == '0') {\n        throw new NumberFormatException(\n            \"cannot infer base when string begins with a 0: \"\n                + Starlark.repr(stringForErrors, StarlarkSemantics.DEFAULT));\n      }\n      base = 10;\n    }\n    if (base < 2 || base > 36) {\n      throw new NumberFormatException(\n          String.format(\"invalid base %d (want 2 <= base <= 36)\", base));\n    }\n\n    // Do not allow Long.parseLong and new BigInteger to accept another +/- sign.\n    if (digits.startsWith(\"+\") || digits.startsWith(\"-\")) {\n      throw new NumberFormatException(\n          String.format(\n              \"invalid base-%d literal: %s\",\n              base, Starlark.repr(stringForErrors, StarlarkSemantics.DEFAULT)));\n    }\n","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/bazelbuild/bazel/blob/e6e199d0601a244511b4cf18c8b2828aa73db1fd/src/main/java/net/starlark/java/eval/StarlarkInt.java#L128-L164","documentation":"StarlarkInt.parse cannot choose a base when the caller passes base=0 ('auto') and the digit string begins with '0' (and is longer than one char). A leading 0 is ambiguous between octal (0755) and decimal-with-padding (0123); Starlark (unlike Python's int, which defaults to decimal) refuses to guess and throws NumberFormatException with this message. Note the 0x/0o/0b prefixes are handled earlier; this path is for unprefixed strings.","triggerScenarios":"int(\"0123\"), int(\"0755\"), int(\"00\") — any call with base omitted (base defaults to 10 only after this check; base=0/auto with leading-zero digits). Commonly hit when porting Python int(\"0755\") code.","commonSituations":"Parsing zero-padded numbers from fixed-width formats (timestamps '0930', zip codes, permissions '0644', IDs with leading zeros); Python-to-Starlark port assuming int() strips leading zeros.","solutions":["Strip leading zeros before converting: int(s.lstrip(\"0\") or \"0\").","Pass the base explicitly when the value is octal: int(\"0755\", 8).","Change the producer to emit unpadded decimal strings."],"exampleFix":"# before\nmode = int(\"0644\")\n\n# after\nmode = int(\"0644\", 8)  # if octal was intended\n# or\nmode = int(\"0644\".lstrip(\"0\") or \"0\")  # if decimal 644 was intended","handlingStrategy":"validation","validationCode":"def parse_decimal(s):\n    s = s.strip()\n    if len(s) > 1 and s.startswith(\"0\") and not s.startswith(\"0x\") and not s.startswith(\"0o\") and not s.startswith(\"0b\"):\n        s = s.lstrip(\"0\") or \"0\"  # zero-padded decimal\n    return int(s, 10)","typeGuard":"def has_leading_zero_ambiguity(s):\n    return len(s) > 1 and s[0] == \"0\" and s[1] not in \"xob\"","tryCatchPattern":null,"preventionTips":["Never rely on int() accepting zero-padded strings; normalize first.","Pass an explicit base (8) for octal permission-style strings."],"tags":["starlark","int-conversion","leading-zero","octal","parsing"],"backgroundTag":null,"analyzedSha":"e6e199d0601a244511b4cf18c8b2828aa73db1fd","analyzedAt":"2026-08-14T10:24:27.848Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}