5.9.3 Key SkyValue Types

recommended

The familiar Skyframe names—FileStateValue, FileValue, PackageValue, ConfiguredTargetValue, ArtifactValue, and ActionExecutionValue—are best read as families of computations in one dependency graph, not as stages in one universal build pipeline. That distinction matters when you trace a rebuild: an edge exists only when one concrete key requested another concrete key during evaluation.1,2

SkyValue types form graph families, not one pipeline
Typical dependencies vary with the concrete key and build request
FILESYSTEM
FileStateValue FileValue DirectoryListingStateValue DirectoryListingValue Paths, symlinks, and directory entries
LOADING & ANALYSIS
PackageValue ConfiguredTargetValue BUILD definitions, configurations, providers, actions
ARTIFACTS & EXECUTION
ArtifactValue ActionExecutionValue Ordinary files are shown. Trees add aggregation.
REPRESENTATIVE RESULT FLOW
BUILD + load + listing valuesPackageValueConfiguredTargetValue nodes
source FileValuesource ArtifactValueconsumer action
producer actiongenerated artifact metadatanext action
Arrows show dependency result → consumer. Raw Skyframe dependency edges point the opposite way. Source edits can reach execution without invalidating package loading.

Start at the filesystem boundary

FileStateValue records the result of inspecting one path with lstat() and, for an existing file, enough additional state to detect a change. It is a leaf family: it does not depend on another Skyframe node. FileValue adds the file view that consumers usually need, including existence, type, resolved path, and symlink resolution. A concrete FileValue depends on the corresponding FileStateValue and may depend on more filesystem nodes while resolving path components or symlinks.1

Directory membership uses a parallel branch, not merely FileValue. DirectoryListingStateValue represents readdir(), while DirectoryListingValue combines that listing with the directory's FileValue. This branch is important for globs: adding a new matching file can change a package even though no previously known source file changed.1

These types do not “apply .bazelignore.” Repository and package discovery have additional computations and policies. A filesystem value answers a question about a path. Whether Bazel considers that path part of a repository or package-loading search is a separate graph concern.

Package and configured-target families describe analysis inputs

PackageValue represents a loaded package, including the result of evaluating its BUILD file. It depends on the BUILD file's FileValue, loaded .bzl computations and other package-loading inputs. Globs add directory-listing dependencies. It does not normally depend on every source file named in the package. Editing app/main.cc, for example, need not change the parsed rule declaration that names main.cc.1,2

ConfiguredTargetValue represents analysis of one target under one configuration. It carries the configured target's providers and the actions registered by its analysis. Its neighborhood includes the package containing the target, configured direct dependencies, configuration-related nodes, toolchain resolution, configured attributes, and other analysis inputs. One label can therefore participate in several ConfiguredTargetValue nodes, and one package can feed many configured targets.1

The relationship is fan-in and fan-out, not a one-to-one progression:

BUILD-file and load inputs ──> PackageValue ──> many configured targets
                                  ▲                     │
configuration and configured deps ─────────────────────┘

The exact edge set is implementation- and request-dependent. Use 5.9.1 Skyframe Data Model's rule—“A requested B”—instead of inferring an edge from the type names alone.

Artifacts bridge analysis and execution

The missing family in the supposed five-node chain is the artifact-value computation. For a source artifact, ArtifactFunction derives file metadata from the associated FileValue. Ordinary generated artifacts bypass ArtifactFunction for memory efficiency: their metadata is accessed directly from the corresponding ActionExecutionValue of the generating action. Tree artifacts can require aggregation of child metadata, while runfiles trees also take a specialized ArtifactFunction path. Do not assume every artifact key follows the ordinary-file case. Conversely, an ActionExecutionValue requests artifact keys for its inputs (plus other execution dependencies), checks the action cache or executes the action, and records output metadata.1,2

That creates alternating producer/consumer relationships in the execution subgraph:

source FileValue ──> source ArtifactValue ──> consuming ActionExecutionValue

producer ActionExecutionValue ──> output ArtifactValue ──> next action

The arrows above use result flow: a dependency's result points toward the computation that consumes it. A raw Skyframe dependency edge uses the opposite orientation—requester → requested key—so the corresponding stored edges are ArtifactValue → FileValue and ActionExecutionValue → input ArtifactValue. Always check a visualization's convention before following its arrows. ConfiguredTargetValue registers actions during analysis, but it is not a simple value dependency through which source bytes flow into action execution. Current Bazel looks up an action from its action-owner data and requests the action's input artifact keys during execution.2

ArtifactValue and ActionExecutionValue are not needed when execution does not run. An analysis-only operation can populate package and configured-target families without evaluating the corresponding action-execution subgraph.1

Trace rebuilds from observed edges, not a memorized chain

Suppose app/main.cc changes. A plausible local trace is:

  1. filesystem invalidation makes the source path's state and file nodes suspect.
  2. the source artifact metadata is re-evaluated.
  3. actions that consume that artifact become candidates for re-evaluation.
  4. changed outputs can affect artifact values consumed by downstream actions.

The package and configured-target nodes may remain reusable because the BUILD declaration and analysis inputs did not change. By contrast, editing app/BUILD.bazel can invalidate package loading and configured analysis, which can change the registered action graph before execution is considered. Adding a file matched by glob() enters through directory-listing nodes. These are three different graph neighborhoods, despite all eventually contributing to a build.1

This model limits what you can conclude from “X rebuilt.” A type-level diagram shows possible families of edges, not the retained keys and edges for this invocation. It also does not prove that an action executed: cache lookup, change pruning, command scope, configuration, action discovery, and execution strategy still matter. 5.9.4 Incrementality Mechanism explains invalidation and change pruning. Use aquery for the planned actions and execution logs or profiles for evidence that an action actually ran.

For an internal investigation, record four facts rather than narrating a pipeline: the changed input, the exact key, the direct reverse dependencies in the retained graph, and the first node whose value or execution evidence actually differs. 5.6.8 Skyscope — Skyframe Visualizer can help inspect a small neighborhood, but internal class names and edges remain version-sensitive implementation details.

key takeaway

The key SkyValue types form interacting filesystem, loading/analysis, and artifact/execution families. PackageValue does not generally depend on every declared source file, and execution is connected through ArtifactValue. The sequence FileStateValue → FileValue → PackageValue → ConfiguredTargetValue → ActionExecutionValue is therefore not a universal dependency chain.

To explain a rebuild, identify the changed concrete key and follow observed reverse dependencies. Separate BUILD or glob changes from source-content changes, and separate graph invalidation from proof that an action executed.

Check your understanding · 3 questions

1.A developer edits only the contents of a source file named in a rule. Which trace is the best starting hypothesis?

Select one answer

2.Match each SkyValue family to the question it primarily answers:

Drag each answer onto the matching prompt, or click an answer and then click a prompt

Answers
PackageValue
ConfiguredTargetValue
ArtifactValue
ActionExecutionValue

3.Evaluate these claims about using SkyValue types to explain rebuilds.

Choose True or False for each sentence

A type-level family diagram proves which actions executed in one invocation.
A BUILD-file edit and a source-content edit can enter different graph neighborhoods.
A glob can introduce directory-listing dependencies into package loading.
If a node is invalidated, every transitive consumer must execute an action.
0 of 3 answered

Footnotes

  1. Skyframe — mapping of filesystem, package, configured-target, artifact, and action-execution families 1 2 3 4 5 6 7 8

  2. Bazel upstream sourcePackageFunction, ConfiguredTargetFunction, ArtifactFunction, and ActionExecutionFunction dependency requests at commit e9e7d623a3d2d41803564b03a2e051a9f1c912d9 (verified 18 July 2026) 1 2 3 4