golang/go · error

GOCACHEPROG didn't return DiskPath in put response

Error message

GOCACHEPROG didn't return DiskPath in put response

What it means

After sending a Put command to the GOCACHEPROG program, the response did not include a DiskPath field. A Put response must tell the Go toolchain where the output was stored on disk so it can be referenced later. An empty DiskPath means the program didn't properly persist the output or didn't report its location — violating the protocol.

Source

Thrown at src/cmd/go/internal/cache/prog.go:344

	}

	if !c.can[cacheprog.CmdPut] {
		// Child is a read-only cache. Do nothing.
		return out, size, nil
	}

	res, err := c.send(c.ctx, &cacheprog.Request{
		Command:  cacheprog.CmdPut,
		ActionID: a[:],
		OutputID: out[:],
		Body:     file,
		BodySize: size,
	})
	if err != nil {
		return OutputID{}, 0, err
	}
	if res.DiskPath == "" {
		return OutputID{}, 0, errors.New("GOCACHEPROG didn't return DiskPath in put response")
	}
	c.noteOutputFile(out, res.DiskPath)
	return out, size, err
}

func (c *ProgCache) Close() error {
	c.closing.Store(true)
	var err error

	// First write a "close" message to the child so it can exit nicely
	// and clean up if it wants. Only after that exchange do we cancel
	// the context that kills the process.
	if c.can[cacheprog.CmdClose] {
		_, err = c.send(c.ctx, &cacheprog.Request{Command: cacheprog.CmdClose})
		if errors.Is(err, errCacheprogClosed) {
			// Allow the child to quit without responding to close.
			err = nil
		}

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Fix or update the GOCACHEPROG program's Put handler to always return DiskPath after successful storage
  2. Check the cache program's logs for storage errors or swallowed exceptions
  3. Temporarily unset GOCACHEPROG to use the default disk cache while debugging
  4. Verify the cache program implements the correct cacheprog protocol version for your Go release
  5. Add error handling in the program to set res.Err instead of silently returning an incomplete response

Example fix

// before: GOCACHEPROG Put handler omits DiskPath
// func handlePut(req *Request) *Response {
//     store.Save(req.ActionID, req.Body)
//     return &Response{}  // missing DiskPath!
// }

// after: always return DiskPath on Put
// func handlePut(req *Request) *Response {
//     path, err := store.Save(req.ActionID, req.Body)
//     if err != nil {
//         return &Response{Err: err.Error()}
//     }
//     return &Response{DiskPath: path}
// }
Defensive patterns

Strategy: validation

Validate before calling

// Verify the GOCACHEPROG program correctly handles Put by performing
// a test Put and checking that the response includes DiskPath.
// This requires speaking the cacheprog JSON protocol.
//
// At minimum, review the program's documentation to confirm Put responses
// include DiskPath for your Go version's protocol.

Type guard

func isMissingPutDiskPath(err error) bool {
    return err != nil && strings.Contains(err.Error(), "didn't return DiskPath in put")
}

Try / catch

// outputID, size, err := progCache.Put(actionID, outputID, size, file)
// if err != nil {
//     if isMissingPutDiskPath(err) {
//         // The cache program has a Put protocol bug.
//         // Fall back to disk cache.
//         os.Unsetenv("GOCACHEPROG")
//         outputID, size, err = diskCache.Put(actionID, outputID, size, file)
//     }
// }

Prevention

When it happens

Trigger: ProgCache.Put() sends a cacheprog.Request with Command=CmdPut, ActionID, OutputID, Body (file path), and BodySize. The response arrives with res.DiskPath == ''.

Common situations: Bug in the GOCACHEPROG program's Put handler — it stores data but doesn't return the storage path; storage backend failure that the program swallows instead of reporting as res.Err; protocol version mismatch where the program's response format is outdated; the program uses an abstract storage model that doesn't map to disk paths.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/303d4c477ca49b52. Report an issue: GitHub.