charmbracelet/crush · error

failed to mark project initialized: %w

Error message

failed to mark project initialized: %w

What it means

MarkProjectInitialized POSTs to /workspaces/{id}/project/init and wraps transport-level request failures with this error. The initialization flag could not be set because the request never completed.

Source

Thrown at internal/client/config.go:190

	defer rsp.Body.Close()
	if rsp.StatusCode != http.StatusOK {
		return false, fmt.Errorf("failed to check project init: status code %d", rsp.StatusCode)
	}
	var result struct {
		NeedsInit bool `json:"needs_init"`
	}
	if err := json.NewDecoder(rsp.Body).Decode(&result); err != nil {
		return false, fmt.Errorf("failed to decode project init response: %w", err)
	}
	return result.NeedsInit, nil
}

// MarkProjectInitialized marks the project as initialized on the
// server.
func (c *Client) MarkProjectInitialized(ctx context.Context, id string) error {
	rsp, err := c.post(ctx, fmt.Sprintf("/workspaces/%s/project/init", id), nil, nil, nil)
	if err != nil {
		return fmt.Errorf("failed to mark project initialized: %w", err)
	}
	defer rsp.Body.Close()
	if rsp.StatusCode != http.StatusOK {
		return fmt.Errorf("failed to mark project initialized: status code %d", rsp.StatusCode)
	}
	return nil
}

// GetInitializePrompt retrieves the initialization prompt from the
// server.
func (c *Client) GetInitializePrompt(ctx context.Context, id string) (string, error) {
	rsp, err := c.get(ctx, fmt.Sprintf("/workspaces/%s/project/init-prompt", id), nil, nil)
	if err != nil {
		return "", fmt.Errorf("failed to get init prompt: %w", err)
	}
	defer rsp.Body.Close()
	if rsp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("failed to get init prompt: status code %d", rsp.StatusCode)

View on GitHub (pinned to 7944b8e522)

Solutions

  1. Verify server availability and re-run MarkProjectInitialized — marking init is safe to retry
  2. Check ctx deadlines if initialization steps are slow
  3. Validate the client's base URL and proxy settings
  4. Inspect the wrapped error to distinguish timeout vs connection refused

Example fix

// before
if err := client.MarkProjectInitialized(ctx, id); err != nil {
    return err
}
// after
if err := client.MarkProjectInitialized(ctx, id); err != nil {
    if ctx.Err() != nil {
        return fmt.Errorf("init mark cancelled: %w", ctx.Err())
    }
    return err
}
Defensive patterns

Strategy: retry

Validate before calling

// Confirm reachability and that the project still needs init before marking
if err := ctx.Err(); err != nil {
    return err
}
needsInit, err := client.ProjectNeedsInitialization(ctx, id)
if err != nil {
    return err
}
if !needsInit {
    return nil
}

Type guard

func isTransportError(err error) bool {
    var netErr net.Error
    return errors.As(err, &netErr)
}

Try / catch

if err := c.MarkProjectInitialized(ctx, id); err != nil {
    var netErr net.Error
    if errors.As(err, &netErr) {
        return retryWithBackoff(ctx, func() error { return c.MarkProjectInitialized(ctx, id) })
    }
    return err
}

Prevention

When it happens

Trigger: Calling Client.MarkProjectInitialized(ctx, id) when the POST fails at the transport layer: server unreachable, connection reset, TLS handshake failure, or the context was cancelled first.

Common situations: Server shut down between the needs-init check and the mark call; laptop sleeping mid-initialization; misconfigured base URL; VPN dropping during project setup.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


AI-assisted analysis of charmbracelet/crush@7944b8e522 (2026-08-29). Data as JSON: /api/errors/88b244b1a0d40fa1. Report an issue: GitHub.