dagger/dagger · error

failed to get tools: %w

Error message

failed to get tools: %w

What it means

Returned by mcpServer.setTools (core/mcpserver.go) when s.env.Tools(ctx) fails to enumerate the tools exposed by the LLM's MCP environment. setTools runs at server startup and after every tool call, so any failure resolving the tool list aborts the MCP server operation. The engine-side cause is wrapped via %w.

Source

Thrown at core/mcpserver.go:84

	for _, tool := range llmTools {
		// Skipping methods that return ID
		if strings.HasSuffix(tool.Name, "_id") {
			continue
		}

		mcpTool, err := genMcpTool(tool)
		if err != nil {
			return nil, err
		}
		mcpTools = append(mcpTools, mcpserver.ServerTool{Tool: mcpTool, Handler: s.genMcpToolHandler(tool)})
	}
	return mcpTools, nil
}

func (s mcpServer) setTools(ctx context.Context) error {
	tools, err := s.env.Tools(ctx)
	if err != nil {
		return fmt.Errorf("failed to get tools: %w", err)
	}
	mcpTools, err := s.convertToMcpTools(tools)
	if err != nil {
		return fmt.Errorf("failed to convert tools to MCP: %w", err)
	}
	s.SetTools(mcpTools...)
	return nil
}

func (s mcpServer) run(ctx context.Context) error {
	ctx, cancel := context.WithCancel(ctx)
	defer cancel()

	if err := s.setTools(ctx); err != nil {
		return err
	}

	errCh := make(chan error)

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Inspect the wrapped error for the root cause (context canceled, query failure, etc.).
  2. Verify the engine connection is alive and retry the dagger mcp command.
  3. If it fires after every tool call, check the state of the bound module/environment — rebind tools and restart.
  4. Ensure no surrounding code cancels the context prematurely.

Example fix

// before
ctx, cancel := context.WithCancel(parent)
defer cancel() // cancels ctx, breaking post-call setTools
// after
ctx, cancel := context.WithCancel(parent)
// keep ctx alive for the lifetime of the MCP server session
Defensive patterns

Strategy: try-catch

Validate before calling

if err := ctx.Err(); err != nil {
    return fmt.Errorf("cannot list tools: context done: %w", err)
}

Try / catch

if err := s.setTools(ctx); err != nil {
    if errors.Is(err, context.Canceled) {
        return nil // shutting down; not a real failure
    }
    return fmt.Errorf("refresh tools failed: %w", err)
}

Prevention

When it happens

Trigger: setTools is invoked (on run startup, or after each tool call from genMcpToolHandler) and env.Tools(ctx) returns an error — engine query failure, canceled context, or broken module/session state.

Common situations: Context canceled while listing tools after a call; engine connection dropped mid-session; the bound module/environment is in a bad state after a failed module load.

Related errors


AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05). Data as JSON: /api/errors/f1ac8f01472f90a4. Report an issue: GitHub.