Skip to content

family.py init _creator_name reads git config user.name through git_out, which decodes strictly, so a name that is not UTF-8 (no --created-by, no GIT_AUTHOR_NAME) ends init, --dry-run included, in a UnicodeDecodeError traceback, exit 1, naming neither the git setting nor the flag that avoids it, where the scaffold refuses the same name by name (#282, #351) #426

Closed

Description

@brettheap

(lane openRepoShape-2, 2026-10-12T17:27Z)

Found by this lane's review of PR #353 (the fix for #292) at dcbc37b, its follow-up F3: family.py init reads git config user.name the way adopt's _elector did before #292. #292 is adopt's, and #282 (PR #351, landed as d82a83e) is the scaffold's; the family holder is the third reader and has neither fix. Reproduced on origin/main 92e29d9 (git 2.43.0, Python 3.12.3), local remotes only, a stub gh. Not claimed.

What is wrong. With no --created-by and no GIT_AUTHOR_NAME, family.py init takes the creator from git config user.name (_creator_name, scripts/family.py:718; the read at :728, called first thing after the identity checks by cmd_init, :1004). It reads through repo_shape.git_out, which decodes strictly (scripts/repo_shape.py:843), and the handler catches Refusal only. A user.name that is not UTF-8 (a name saved in a legacy code page: Jos<e9>) is a UnicodeDecodeError, so init ends in a traceback, exit 1, under --dry-run as well, naming neither the git setting nor the flag that avoids it (--created-by). Nothing is created: the read is before the holder's remote and work directory. The scaffold's _elector reads the same setting as bytes and refuses a name no file can hold by name (#282):

# $U: a checkout of openRepoShape at 92e29d9. Local; no network. The name is given in command scope so a checkout's own config cannot outrank it:
GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=user.name GIT_CONFIG_VALUE_0="$(printf 'Jos\xe9')" \
  python3 "$U/scripts/family.py" init --org testorg --family Contoso --local-remote-dir "$D/remotes" --into "$D/into"
#   exit 1
#   Traceback: family.py line 728, in _creator_name -> scripts/repo_shape.py line 843, in git_out
#   UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe9 in position 3: invalid continuation byte
the run result at 92e29d9
family.py init, user.name Jos<e9>, no --created-by exit 1, UnicodeDecodeError from _creator_name (:728); --dry-run the same; no remote, no family folder
the same with --created-by 'T H' (control) exit 0
user.name Jose, no --created-by (control) exit 0, created_by: "Jose"
scaffold-project.py, the same user.name, no --elected-by (the twin) exit 2, REFUSED scaffold-unwritable-value: --elected-by (not given, so git config user.name) is 'Jos\udce9', which the scaffold writes into ... and it holds a byte that is not UTF-8, nothing created

What it should do. Refuse by name before anything exists, --dry-run alike, as the scaffold does: read the setting as bytes, decode with surrogateescape, and ask the shared question (unwritable_values, scripts/shape_materialize.py:1068, the function the scaffold and adopt use) so that a name no file can hold is a refusal of its own (exit 2, a code such as family-unwritable-value) that says it came from git config user.name and says to pass --created-by 'Your Name'. Do not change git_out (scripts/repo_shape.py is a pinned copy; a change moves the sha every project's contracts/shape-pin.yaml records for it). The value is also wanted by family-manifest-invalid-style refusals PR #397 adds for --created-by ' ': the two should agree on how the creator is named ("not given, so GIT_AUTHOR_NAME or git config user.name", PR #397's _manifest_flags).

How to test. In the family tests' harness (tests/test_family.py or beside PR #397's tests/test_family_init_values.py), with the name in command scope (GIT_CONFIG_COUNT) or a GIT_CONFIG_GLOBAL file written with write_bytes (tests/test_scaffold_ignored_shape_files.py:64-77 does the same for excludes): init and init --dry-run exit 2 with the new code, the message names git config user.name, and no remote or folder exists; --created-by given, or a UTF-8 name, still initialises. Skip where the filesystem or git configuration cannot carry the byte (Windows).

Not in this issue. --created-by/GIT_AUTHOR_NAME holding a non-UTF-8 byte (the argument reaches the holder's family.yaml as an escaped lone surrogate, "Jos\udce9", and validate-family.py accepts it; a neighbouring lone-surrogate question; compare #280 for the project manifest). scaffold-project.py (#282) and adopt (#292, PR #353).

Related: #282 and PR #351 (the scaffold, landed); #292 and PR #353 (adopt); #307 and PR #397 (the other values init writes without asking whether the holder can hold them).

Lane: openreposhape-2 (openRepoShape-2)

Activity

  1. added this to the v1.1.0 milestone on Oct 15, 2026
  2. brettheap commented on Oct 15, 2026

    @brettheap
    ContributorAuthor

    CLAIMED — lane openRepoShape-4, session 11c6c0ef-495a-4a05-94cf-811b7b0a1012@Eagle, 2026-10-15T22:58:56Z, for #426

    Logged in lanes/log/openRepoShape-4.md at 990b6cc3c5d339dfd2c7f44a0b0aac9d20da7174.

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

    1. existing `CLAIMED —` comments on opensoft/openRepoShape#426:
       none
    2. `gh pr list --repo opensoft/openRepoShape --state all --search "#426"`, kept where the row or its body names `#426`:
       none
    3. `git ls-remote --heads git@github.com:opensoft/openRepoShape` branches naming `426` as a whole token:
       none
    
  3. added a commit that references this issue on Oct 16, 2026
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