Skip to content

bug: Starlark auto-invoked function ignores context cancellation and bypasses the logger #156

Description

@robbyt

Summary

When a Starlark script returns a callable (the "auto-invoke main()" idiom), the evaluator calls it on a bare starlark.Thread with no context-cancellation wiring and no Print handler. A long-running or infinite auto-invoked function ignores ctx deadlines, and its print() output bypasses the configured logger.

Root cause

engines/starlark/evaluator/evaluator.go:210-223:

if callable, ok := result.Value.(starlarkLib.Callable); ok {
	thread := &starlarkLib.Thread{Name: "func"}   // no AfterFunc/Cancel, no Print
	val, err := starlarkLib.Call(thread, callable, nil, nil)
	...
}

The top-level exec path (evaluator.go:97-110) wires both:

thread := &starlarkLib.Thread{Name: "eval", Print: func(...) { logger.InfoContext(...) }}
stop := context.AfterFunc(ctx, func() { thread.Cancel(ctx.Err().Error()) })
defer stop()

The auto-call thread has neither, so thread.Cancel is never invoked when ctx is done.

Reproduction (confirmed — measured)

With a 100 ms timeout context and a returned function running a long loop, the auto-called function ran ~19.5 s to completion and Eval returned success — the expired context was never observed. Control: the same loop at top level (inside prog.Init) aborts at ~100 ms with a cancellation error.

Impact

High — the documented "return a function to run it" pattern is exempt from the timeout and cancellation guarantees the top-level path provides, and its diagnostic output escapes the logger.

Fix

Use the same thread setup on the call path: attach the Print handler and wire context.AfterFunc(ctx, ...) → thread.Cancel(...) with defer stop(). Optionally pre-check ctx.Err() before the call. Add a test asserting a cancelled context aborts an auto-invoked function.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions