Repository navigation
fix(api): never send push_commands as null; guard it in the console - #1
Merged
Merged
Conversation
Selecting any tile but yocto on the snippets screen threw `TypeError: can't access property "length", ... push_commands is null` and left the skeleton placeholder up forever. Every non-yocto builder -- and yocto on a project without sstate/downloads -- leaves the PushCommands slice nil, which encoding/json marshals as `null`, and the page read `.length` off it unguarded (files/env were already guarded). - snippetResponse normalises nil to an empty slice, so push_commands is an array on the wire for every tool and both the minted and preview branches (same convention as newProject's backends). - The page reads push_commands through a `?? []` derived, like files and env, and the "nothing to show" empty state now names the backend kind the selected tool needs and links to the project's backends page. - TestSnippetPushCommandsIsAnArrayOnTheWire asserts the JSON body, not the decoded struct: `len(nil) == 0` let every existing len-based check pass while the wire carried null. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NonmtCqhSy8f13VcK1rBMb
Review findings on the parent commit, all in the reworked empty state:
- The "Configure backends" button linked /o/{org}/p/{project}/backends,
a route that does not exist -- the remediation CTA landed on the
not-found page. Now projectPath(...)/backends/new, the same target the
overview page uses (ConsoleNav documents this exact trap).
- The copy asserted "there isn't one. Add it" for a state also reached
when the backend exists but is disabled -- following it earned a 409
from the (project_id, kind) unique. The copy now defers to the
warnings, which carry the missing-vs-disabled distinction.
- The mint bar is now gated on the preview having content: minting on a
backend-less tile created a real one-time secret with no blocks to
bake it into, rendered above an empty state whose advice (pick the
tile again) would wipe it. hasContent is one shared derivation, so the
mint bar and the empty state cannot disagree.
- "a oci backend" -> "the oci backend" on four of nine tiles.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YM78iXWsYNLXccdzKhQcx1
A bare getByText('live') matches every live token's status badge; the
seeded dev user's table holds one per prior run against a reused local
database, so the assertion is a strict-mode violation everywhere but
CI's fresh database. Same ambiguous-locator class as the robot-row fix
(5ed6dcd), same remedy: scope to the row the test just created.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YM78iXWsYNLXccdzKhQcx1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
On
/o/{org}/p/{project}/snippets, selecting any tile except Yocto hangs on the skeleton placeholder withEvery non-yocto builder (and yocto on a project with no sstate/downloads backend) leaves
snippetContent.pushCommandsnil.encoding/jsonmarshals a nil slice asnull, and the page didresponse.push_commands.lengthunguarded —filesandenvalready had?? []guards, this one didn't. The server returned 200 every time, so nothing in the logs pointed at it.Reproduced in v0.1.0 against a project with a configured bazel backend; the new test's failure output before the fix is literally the user-visible body:
Fix
snippetResponsenormalises nil →[]string{}, sopush_commandsis an array on the wire for every tool and both the minted and preview branches (same conventionnewProjectuses forbackends).push_commandsis read through a?? []derived likefiles/env. The "Nothing to show" empty state now names the backend kind the selected tool needs and links to the project's backends page, so a project without that backend gets told what to do instead of a generic shrug.TestSnippetPushCommandsIsAnArrayOnTheWireasserts the JSON body contains"push_commands":[]and nevernull, for bazel (minted + preview), docker, and yocto-with-no-backends. The existinglen(out.PushCommands) != 0checks pass on nil, which is why this slipped through; the tscontract test also hand-buildsPushCommands: []string{}and so never exercised the real path.Verification
go test ./internal/api/ok; new test fails onmain, passes herego vet ./...,go tool golangci-lint run ./internal/api/...— 0 issuesnpm run check— 0 errors;npm test— 243 passed;npm run buildok🤖 Generated with Claude Code
https://claude.ai/code/session_01NonmtCqhSy8f13VcK1rBMb