> ## Documentation Index
> Fetch the complete documentation index at: https://docs.genlabs.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Devcontainer

> GitHub auth failures, docker exec PATH gotchas, and rust-analyzer not surfacing errors inside the workshop devcontainer.

<Accordion title="Cargo / git GitHub auth fails inside the devcontainer">
  You'll see one of these on `cargo fetch` / `cargo build` / `gen genie build`:

  ```
  failed to acquire username/password from local configuration
  fatal: could not read Username for 'https://github.com': terminal prompts disabled
  ```

  ### Why it happens

  The workshop repos pull framework dependencies from the private
  `gen-bc/gen-framework-preview` GitHub repo over HTTPS. Cargo delegates the
  fetch to the `git` CLI (because `.cargo/config.toml` sets
  `net.git-fetch-with-cli = true`), so `git` has to be able to authenticate
  non-interactively. The token flows host → container like this:

  ```
  host gh keyring ──(gh auth token)──> host env GH_TOKEN
     └─ devcontainer.json "GH_TOKEN": "${localEnv:GH_TOKEN}"
          └─ container env GH_TOKEN
               └─ post-create.sh installs a git credential helper that feeds
                  username=x-access-token / password=$GH_TOKEN to git over HTTPS
                    └─ cargo fetch (git-fetch-with-cli) authenticates
  ```

  Anything that breaks a link produces the errors above.

  ### Step-by-step diagnosis

  **1. Confirm `git-fetch-with-cli` is enabled**

  ```bash theme={null}
  cat .cargo/config.toml      # should contain [net] git-fetch-with-cli = true
  ```

  <Note>
    `[net]` only works in **`.cargo/config.toml`**, NOT in `Cargo.toml`. If you
    see `warning: unused manifest key: net` during a build, you have a stray
    `[net]` block in `Cargo.toml` — remove it; it does nothing there.
  </Note>

  **2. Check whether the token reached the container**

  ```bash theme={null}
  [ -n "$GH_TOKEN" ] && echo "GH_TOKEN set (${#GH_TOKEN} chars)" || echo "GH_TOKEN EMPTY"
  gh auth status
  ```

  * **`GH_TOKEN EMPTY`** → the token never made it in. Fix on the **host**:

    ```bash theme={null}
    # host shell:
    export GH_TOKEN=$(gh auth token)
    ```

    `gh` stores its token in the OS keyring, not as an env var, so you must
    export it. Then relaunch VS Code **from that terminal** (`code .`) or set it
    machine-wide and rebuild the container:

    ```bash theme={null}
    # macOS, persists across logins:
    launchctl setenv GH_TOKEN "$(gh auth token)"
    ```

  * **`GH_TOKEN` set** → continue.

  **3. Reproduce the failure with a raw git fetch**

  ```bash theme={null}
  GIT_TERMINAL_PROMPT=0 git ls-remote https://github.com/gen-bc/gen-framework-preview HEAD
  ```

  * **Returns a commit SHA** → auth works; your problem is elsewhere (network,
    wrong tag/ref, `Cargo.lock`). Stop here.
  * **`gh: not found` or `could not read Username`** → the credential helper is
    broken. Continue to step 4.

  **4. Inspect the git credential helper**

  ```bash theme={null}
  git config --global --get-all credential.https://github.com.helper
  which gh
  ```

  The classic failure: the helper points at a **host path** that doesn't exist
  in the Linux container, e.g.:

  ```
  !/opt/homebrew/bin/gh auth git-credential
  ```

  This happens because VS Code's "Dev Containers" extension copies your host
  `~/.gitconfig` into the container, including the credential helper line that
  `gh auth setup-git` wrote on your Mac (which hard-codes
  `/opt/homebrew/bin/gh`).

  **5. Fix the credential helper (immediate, in the running container)**

  Replace the broken helper with a token-backed one that doesn't depend on
  where `gh` lives:

  ```bash theme={null}
  git config --global --unset-all credential.https://github.com.helper 2>/dev/null || true
  git config --global --unset-all credential.https://gist.github.com.helper 2>/dev/null || true
  git config --global credential.helper "" 2>/dev/null || true
  git config --global --add credential.https://github.com.helper \
    '!f() { if [ "$1" = get ] && [ -n "${GH_TOKEN:-}" ]; then echo username=x-access-token; echo "password=${GH_TOKEN}"; fi; }; f'
  ```

  Verify:

  ```bash theme={null}
  GIT_TERMINAL_PROMPT=0 git ls-remote https://github.com/gen-bc/gen-framework-preview HEAD
  ```

  **6. Make the fix durable**

  The container's `~/.gitconfig` isn't on a persistent volume, and VS Code
  re-injects the host gitconfig on every connect, so step 5 alone is temporary.
  Pick one permanent fix:

  * **Preferred — stop VS Code copying the host gitconfig.** Add to VS Code
    **user** `settings.json`:

    ```json theme={null}
    "dev.containers.copyGitConfig": false
    ```

  * **Or** fix the host gitconfig so the copied path is valid in both OSes —
    use a bare `gh` instead of an absolute Homebrew path:

    ```bash theme={null}
    git config --global --replace-all credential.https://github.com.helper '!gh auth git-credential'
    git config --global --replace-all credential.https://gist.github.com.helper '!gh auth git-credential'
    ```

    `gh` resolves to `/opt/homebrew/bin/gh` on the host and `/usr/bin/gh` in
    the container, so the same line works in both.

  **7. Force a real authenticated fetch to prove it end-to-end**

  A plain Rebuild Container doesn't re-fetch — the cargo cache volume keeps
  the cached git deps. Force a real network fetch:

  ```bash theme={null}
  export PATH="/home/vscode/.cargo/bin:$PATH"
  export CARGO_TARGET_DIR="/workspaces/<repo>/devcontainer_target"
  rm -rf ~/.cargo/git/db/gen-framework-preview-* ~/.cargo/git/checkouts/gen-framework-preview-*
  cd <contract-workspace>
  cargo fetch    # should print: Updating git repository `https://github.com/gen-bc/...`
  ```

  ### One-liner triage

  Inside the container:

  ```bash theme={null}
  echo "GH_TOKEN: ${GH_TOKEN:+set}${GH_TOKEN:-EMPTY}"; \
  git config --global --get-all credential.https://github.com.helper; \
  which gh; \
  GIT_TERMINAL_PROMPT=0 git ls-remote https://github.com/gen-bc/gen-framework-preview HEAD | head -1
  ```

  ### Host vs container quick reference

  | Concern                | Host (macOS)                                                | Container (Ubuntu)                                  |
  | ---------------------- | ----------------------------------------------------------- | --------------------------------------------------- |
  | `gh` binary location   | `/opt/homebrew/bin/gh`                                      | `/usr/bin/gh`                                       |
  | gh credential storage  | OS keyring                                                  | `GH_TOKEN` env / gh-auth volume                     |
  | Token as env var?      | No (keyring) — `export GH_TOKEN=$(gh auth token)` to expose | Yes, via `${localEnv:GH_TOKEN}`                     |
  | git credential storage | `osxkeychain`                                               | helper backed by `GH_TOKEN`                         |
  | Why helpers break      | —                                                           | host path `/opt/homebrew/bin/gh` doesn't exist here |
</Accordion>

<Accordion title="`docker exec` into the container loses PATH and CARGO_TARGET_DIR">
  `remoteEnv` from `devcontainer.json` is only applied to the VS Code terminal,
  not to `docker exec` sessions. If you're shelling in directly, export them
  yourself before running cargo / gen:

  ```bash theme={null}
  export PATH="/home/vscode/.cargo/bin:$PATH"
  export CARGO_TARGET_DIR="/workspaces/<repo>/devcontainer_target"
  ```
</Accordion>

<Accordion title="rust-analyzer / flycheck errors don't surface in the IDE">
  VS Code's cargo wrapper inside the devcontainer can strip PATH, leaving
  rust-analyzer unable to invoke the right toolchain. Symptom: code compiles
  fine on the command line, but the IDE shows no errors or shows stale ones.

  Workarounds:

  * Reload the VS Code window after the container finishes setting up
    (`Developer: Reload Window`).
  * Confirm `which cargo` resolves inside the **integrated terminal** (the
    one VS Code reuses for rust-analyzer) to `/home/vscode/.cargo/bin/cargo`,
    not `/usr/bin/cargo`.
  * If still wrong, add `~/.cargo/bin` explicitly to the front of `PATH` in
    the VS Code terminal profile.
</Accordion>

<Note>
  Hit something not on this page? Send the failing command and the full error
  output to your Gen Labs contact — the page grows from real reports.
</Note>
