Skip to content

bootstrap.py and repo_shape.py: a leg on a branch whose name is not UTF-8 makes every later make bootstrap end in a UnicodeDecodeError, and a character the filesystem encoding lacks still ends step (a) in a traceback #710

Closed

Description

@brettheap

repo_shape.git_out should hand a branch name that is not UTF-8 back to its callers, so that a leg on such a branch does not end every later make bootstrap in a traceback. The riders about names step (a) carries or cannot write ride with it.

From lane 4's checklist triage of 2026-10-16 (T2), approved by Brett Heap at 2026-10-16T13:36:07Z ("approve all triage recommendations"). One pull request covers the lines below, and it is the SAME pull request as #709, so that templates/assembly-root/scripts/bootstrap.py is re-pinned once and not twice.

Parent: #459. Milestone: v1.1.1 (a follow-up filed after Brett Heap's v1.1.1 word of 2026-10-16T13:35:28Z).

Authored after the v1.1.0 work; lands after the v1.1.0 tag unless the release owner (lane 3) says otherwise.

Lands after:

Effort: S: one decode rule in git_out. L4-124 waits for its ruling. Platform: all (L4-124 was measured under LC_ALL=C PYTHONUTF8=0, because the review host has no Latin-1 locale).

Files: scripts/repo_shape.py (git_out, :1048 on c6122e8) and templates/assembly-root/scripts/bootstrap.py; both are pinned shape copies, re-pinned once, in the same pull request as #709.

Lane openRepoShape-4 claims it at filing; see its CLAIMED comment.

Why this is filed. Not an ordinary repository: the branch name has to be one that is not UTF-8, which bootstrap.py --branch $'a\xffb' (which #644 deliberately keeps), a manifest's "\udcXX" escape or a hand edit makes. But once it exists, EVERY later make bootstrap in that root ends in a traceback until the branch is renamed by hand, with nothing naming it. Line numbers are at c6122e8 (#639); main has moved since.

Lines

Rides along (backlog; tick it here if the same change covers it)

  • L4-124 (NEEDS A RULING): a character the filesystem encoding lacks still ends bootstrap's step (a) in a traceback. The same on main and on the head. Measured with LC_ALL=C PYTHONUTF8=0, because this host has no Latin-1 locale (locale -a: C, C.utf8, POSIX) and sys.getfilesystemencoding() is then ascii, the same mechanism: tracking_branch: "feature/日本" gives the validator 0 manifest ok, then bootstrap 1, UnicodeEncodeError: 'ascii' codec can't encode characters in position 19-20: ordinal not in range(128). Under the default UTF-8 locale the same value creates feature/日本. assembly-root bootstrap.py: a lone surrogate or NUL in tracking_branch (or a leg's branch:) ends make bootstrap in a subprocess traceback in step (a), and validate-manifest.py says manifest ok, so no tool names it #455's own "Survive it" asks that "a branch the platform cannot hand to git" be treated as one git refuses, and bootstrap.py and validate-manifest.py: a branch holding a NUL or a lone surrogate is a finding and step (a) does not hand it to git, so tracking_branch: "a\ud83db" or a leg's branch: "a\x00b" no longer ends make bootstrap in a subprocess traceback under a manifest ok (#455) #644 scoped it out on purpose (the _argument_fault docstring). Where: bootstrap.py:125 (_argument_fault asks NUL and lone surrogates only). Shape of a fix: fault wherever _fsencoded_length(char) == 0. It needs its own remediation (the name is good; run under a UTF-8 locale or PYTHONUTF8=1), which changes what a person is told, so it needs a ruling of its own (R455 O1). (source)
  • L4-126 (a question; R455 recommends no change here, and the fix at L4-125): step (a) CARRIES a manifest value holding U+DC80 to U+DCFF that step (b) then names as a finding. tracking_branch: "a\udcffb", or a leg's branch: "\udc80": step (a) creates and checks out refs/heads/a\xffb (resp. refs/heads/\x80) in each leg, because _argument_fault asks only whether os.fsencode can write the surrogate as one byte, and then the validator names the value (U+DCFF / U+DC80). Following the finding (editing back to main) and running again ends in UnicodeDecodeError (measured: bootstrap 1, make 2). That is L4-125's decode, the same on main, where the validator said nothing. Two options: (a) _checkout_all_tracking_branches (bootstrap.py:840) asks the validator's any-surrogate rule of a value from the manifest and keeps the os.fsencode rule for --branch alone, about 6 lines and one test, so step (a) never acts on a value step (b) refuses; (b) leave it and fix the root cause in L4-125. R455 recommends (b): the input is hand-written and exotic, and (a) only hides one route into L4-125 (R455 F4). (source)

What is expected

  • git_out has ONE decode rule for what git prints, and a later make bootstrap on a leg whose branch is a\xffb ends branch ... at ... and not a traceback. The rule is the pull request's to choose, but it must keep the name's bytes, since the name goes back to git. A test makes the branch with git branch $'a\xffb' (POSIX only; skipped where the filesystem refuses the name, as the repository's other such tests are) and runs bootstrap twice.
  • L4-126 is answered by that fix, option (b), unless Brett Heap rules for option (a). The pull request says so and ticks it.
  • L4-124 is NOT in the first change. It waits for a ruling from Brett Heap on what a person is told when the platform's encoding cannot write a good branch name, and stays open here until then.

Not a duplicate: lane 5's #694 is a missing git, not a name git cannot decode. No issue numbered #650 to #700 cites L4-124 to L4-126 (read at 13:17Z); #425 is the adopt-project.py reader of the same decode.

Each line above is a line of #459's checklist comment (issuecomment-6214587074). Tick it there too when this closes.

Lane: openreposhape-4 (openRepoShape-4)

Activity

  1. added this to the v1.1.1 milestone on Oct 16, 2026
  2. brettheap commented on Oct 16, 2026

    @brettheap
    ContributorAuthor

    CLAIMED — lane openRepoShape-4, session 11c6c0ef-495a-4a05-94cf-811b7b0a1012@Eagle, 2026-10-16T13:59:14Z, for #710

    Logged in lanes/log/openRepoShape-4.md at ab8737076b7a5f02b1ef962b466fff43396cc781.

    The three reads (lane-collision-protocol Rule 1):

    1. existing `CLAIMED —` comments on opensoft/openRepoShape#710:
       none
    2. `gh pr list --repo opensoft/openRepoShape --state all --search "#710"`, kept where the row or its body names `#710`:
       none
    3. `git ls-remote --heads git@github.com:opensoft/openRepoShape` branches naming `710` as a whole token:
       none
    
  3. brettheap commented on Oct 17, 2026

    @brettheap
    ContributorAuthor

    (lane openRepoShape-5, 2026-10-16T23:59:42Z) One more site for #710, so no separate issue is filed for it. _upstream_holding in the assembly root's bootstrap.py (templates/assembly-root/scripts/bootstrap.py:222 at main 66b230ed) reads for-each-ref's upstream name as strict UTF-8, the same flaw that lane 5's #704 (PR #745) fixed in _head_of by reading bytes and decoding with os.fsdecode. rv704 measured it at a1f2433f and at 4e2b211b: with a tracking branch past the pin whose name and upstream are not UTF-8, and HEAD detached at the pin, bootstrap ends in a UnicodeDecodeError at _upstream_holding. The fix is the same as #745's.

  4. brettheap commented on Oct 17, 2026

    @brettheap
    ContributorAuthor

    (lane openRepoShape-4, 2026-10-17T13:01:33Z) Brett Heap's ruling on L4-124, at 2026-10-17T13:01:07Z: "go with (a) for L4-124".

    The case: under LC_ALL=C PYTHONUTF8=0, the filesystem encoding is ascii. There, tracking_branch: "feature/日本" passes the validator (manifest ok), and bootstrap then fails with a UnicodeEncodeError traceback.

    Option (a), as ruled:

    • _argument_fault also faults any character that os.fsencode cannot write.
    • The refusal gets its own line, which says three things:
      • the name itself is good;
      • this system's encoding, named, cannot write it;
      • the way out is to run bootstrap under a UTF-8 locale (LC_ALL=C.UTF-8) or with PYTHONUTF8=1.
    • The leg is left as it is.

    Rejected:

    Lane 4's writer for #710 resumes with this ruling. Like every v1.1.1 PR, it waits for the v1.1.0 tag.

  5. brettheap commented on Oct 17, 2026

    @brettheap
    ContributorAuthor

    (lane openRepoShape-4, 2026-10-17T19:01:27Z) Where #710's decode rule lives: Option 2, as lane 4 ruled on 2026-10-17. This issue expected that "git_out has ONE decode rule". PR #824 puts that rule in the assembly root's bootstrap.py, in _try_git, and leaves repo_shape.git_out's strict UTF-8 decode as it is.

    A comment at _try_git's decode records this ruling (RV824's N6).

    Lane: openreposhape-4 (openRepoShape-4)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions