pub enum WorkspaceDiagnosticKind {
Show 13 variants
UndeclaredWorkspace,
MalformedPackageJson {
error: String,
},
GlobMatchedNoPackageJson {
pattern: String,
},
MalformedTsconfig {
error: String,
},
TsconfigReferenceDirMissing,
MalformedPnpmWorkspaceYaml {
error: String,
},
SkippedLargeFile {
size_bytes: u64,
},
SkippedMinifiedFile {
size_bytes: u64,
},
SkippedSourceDotdir,
SourceReadFailure {
error: String,
},
BunLockbOverrideResolutionSkipped,
BunLockOverrideResolutionSkipped,
BunResolutionsShadowedByOverrides,
}Expand description
Why a workspace-discovery candidate was rejected, or why a sibling directory looked workspace-like but was not declared.
Wire-format names are kebab-case so JSON consumers (CI integrations, MCP agents, LSP clients) get a stable, language-neutral identifier.
Variants§
UndeclaredWorkspace
A directory contains package.json but is not declared as a workspace
in package.json workspaces, pnpm-workspace.yaml, or
tsconfig.json references. Surfaced by
find_undeclared_workspaces.
MalformedPackageJson
A declared workspace’s package.json failed to parse. The directory is
dropped from discovery, but analysis still proceeds (degraded).
GlobMatchedNoPackageJson
A workspace glob pattern matched a directory that contains no
package.json. Honors the extended skip list and ignorePatterns
before emitting.
MalformedTsconfig
tsconfig.json exists at the root but failed to parse. Project
references cannot be discovered.
TsconfigReferenceDirMissing
tsconfig.json lists a references[].path that does not point to an
existing directory.
MalformedPnpmWorkspaceYaml
pnpm-workspace.yaml exists but failed to parse as YAML. Catalog and
dependency-override analysis proceeds with no entries (degraded), so
catalog:-referenced dependencies may be misclassified until the
syntax is fixed.
SkippedLargeFile
A source file was skipped at discovery because it exceeds the configured
per-file size limit (--max-file-size / FALLOW_MAX_FILE_SIZE, default
5 MB). The file is never read, parsed, or analyzed, guarding against the
out-of-memory blowup a single multi-MB generated/vendored/bundled file
causes (issue #1086). Surfaced by source discovery, not workspace
discovery, but shares this channel so the skip is visible in
workspace_diagnostics[] on fallow dead-code / dupes / health JSON.
SkippedMinifiedFile
A large JavaScript bundle was skipped at discovery because it appears to
be minified generated output. The file is never parsed or analyzed,
guarding against sub-limit bundles that can still create very large ASTs
and extraction payloads (issue #1086). Use --max-file-size 0 when the
bundled file really should be analyzed.
SkippedSourceDotdir
A dot-prefixed directory was not traversed by source discovery even
though it contains at least one source file the project has not
excluded. Hidden directories are skipped by default apart from a small
convention allowlist (.storybook, .vitepress, .well-known,
.changeset, .github) and the directories an active framework plugin
or a package.json script reference contributes, so files inside are
never parsed and their imports and exports are invisible to every
analysis. No config field adds a directory to traversal: run fallow
with --root against the directory to analyze it on its own, or add it
to ignorePatterns to silence this (issue #461).
“Not excluded” is measured the way the run measures it: a directory
whose contents are gitignored, or excluded by ignorePatterns, or (on
a --production run) excluded as test or story files, never earns this
diagnostic, because the advertised remedies would find nothing there
either. Generated tool output and non-git VCS metadata are excluded by
name.
The advisory is best-effort and bounded: one run inspects a fixed number of skipped directories with a fixed I/O budget, in sorted path order, so a pathological tree yields a deterministic prefix rather than an unbounded array or an unbounded scan. The stderr note says “at least” when a ceiling bound the run.
Surfaced by source discovery, not workspace discovery, but shares this
channel so the skip is visible in workspace_diagnostics[] on
fallow dead-code / dupes / health JSON.
Unlike the two skipped-file kinds beside it, this one is CAPPED. To
bound the directory reads the check costs, a run classifies at most 64
candidate directories and spends at most 1024 directory entries across
all of them, so on a project that exceeds either ceiling the array is a
prefix of the skipped directories rather than all of them, and the
stderr note says “at least N”. No measured repository comes close to
either ceiling. A consumer needing an exact total should run fallow
with --root against the tree rather than infer one from this array.
SourceReadFailure
A source discovered with a stable FileId
could not be read before parsing. Analysis continues with the remaining
sparse module IDs and reports the underlying filesystem or UTF-8 error.
BunLockbOverrideResolutionSkipped
Dependency-override resolution was skipped because bun’s legacy binary
bun.lockb sits next to this package.json, fallow cannot read the
binary format, and no parseable text lockfile was found to use
instead: no bun.lock that parses, and no readable pnpm-lock.yaml,
package-lock.json, or npm-shrinkwrap.json. A yarn.lock is never
consulted (yarn ignores overrides), so it does not prevent the skip
either. The manifest declares overrides, so the
unused-dependency-overrides check would otherwise have run; without
resolution ground truth it would flag every transitive-only pin, so no
unused-override findings are reported at all (issue #2358). Surfaced
by the override analysis, not workspace discovery, but shares this
channel so the skip is visible in workspace_diagnostics[] JSON and
as a stderr warning.
BunLockOverrideResolutionSkipped
Dependency-override resolution was skipped because bun’s text
bun.lock exists but could not be parsed and no readable pnpm or npm
lockfile was available as independent resolution ground truth.
BunResolutionsShadowedByOverrides
A bun manifest declares both overrides and a non-empty resolutions
object. Bun applies overrides and ignores resolutions, so fallow
reports the shadowed configuration without offering removal advice.
Implementations§
Source§impl WorkspaceDiagnosticKind
impl WorkspaceDiagnosticKind
Sourcepub const fn id(&self) -> &'static str
pub const fn id(&self) -> &'static str
Stable kebab-case identifier used in dedupe keys and tracing payloads.
Sourcepub const fn is_source_discovery(&self) -> bool
pub const fn is_source_discovery(&self) -> bool
Whether this diagnostic is produced by SOURCE discovery (the file walk in
discover_files) rather than WORKSPACE discovery (config load). Source-
discovery diagnostics are APPENDED to the registry after config load, so
stash_workspace_diagnostics must preserve them when it replaces the
workspace-discovery set, otherwise the per-analysis config re-loads in
combined-mode (fallow with no subcommand re-loads config for check,
dupes, and health) wipe them before the JSON envelope is built (issue
#1086).
Sourcepub const fn is_source_walk_recorded(&self) -> bool
pub const fn is_source_walk_recorded(&self) -> bool
Whether this diagnostic is written by the source file WALK
(discover_files), the subset of Self::is_source_discovery that a
walk replaces wholesale for its root. source-read-failure is the
other source-discovery kind and is NOT one of these: the parse stage
records it after the walk, so it has to keep reaching consumers through
the registry.
A walk-recorded entry must reach an analysis from its OWN walk’s return
value. Combined mode runs the dead-code and duplication walks under
rayon::join whenever a per-analysis production split stops them from
sharing a file list, so a registry read answers “whichever walk wrote
last” and varies between runs of the same command (issue #2366).
Sourcepub const fn is_analysis_stage(&self) -> bool
pub const fn is_analysis_stage(&self) -> bool
Whether this diagnostic is recorded by the ANALYZE stage (the
dependency-catalog and override detectors) rather than by workspace or
source discovery. Analysis-stage diagnostics reach the registry through
record_workspace_diagnostics after config load, so
stash_workspace_diagnostics must preserve them across combined-mode’s
per-analysis config re-loads, and every analyze pass clears its previous
entries before re-recording so a fixed cause drops out on the next run
(issue #2366). The match is exhaustive on purpose: a new kind must be
classified here before it compiles.
Classify a kind true ONLY when a detector reachable from the dead-code
analyze pass (find_dead_code_full) re-records it, because that pass is
the single clear site. A kind recorded exclusively by another stage would
be cleared by the next dead-code pass and never come back.
Trait Implementations§
Source§impl Clone for WorkspaceDiagnosticKind
impl Clone for WorkspaceDiagnosticKind
Source§fn clone(&self) -> WorkspaceDiagnosticKind
fn clone(&self) -> WorkspaceDiagnosticKind
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for WorkspaceDiagnosticKind
impl Debug for WorkspaceDiagnosticKind
Source§impl<'de> Deserialize<'de> for WorkspaceDiagnosticKind
impl<'de> Deserialize<'de> for WorkspaceDiagnosticKind
Source§fn deserialize<__D>(
__deserializer: __D,
) -> Result<WorkspaceDiagnosticKind, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(
__deserializer: __D,
) -> Result<WorkspaceDiagnosticKind, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
impl Eq for WorkspaceDiagnosticKind
Source§impl Hash for WorkspaceDiagnosticKind
impl Hash for WorkspaceDiagnosticKind
Source§impl JsonSchema for WorkspaceDiagnosticKind
impl JsonSchema for WorkspaceDiagnosticKind
Source§fn schema_id() -> Cow<'static, str>
fn schema_id() -> Cow<'static, str>
Source§fn json_schema(generator: &mut SchemaGenerator) -> Schema
fn json_schema(generator: &mut SchemaGenerator) -> Schema
Source§fn inline_schema() -> bool
fn inline_schema() -> bool
$ref keyword. Read moreSource§impl PartialEq for WorkspaceDiagnosticKind
impl PartialEq for WorkspaceDiagnosticKind
Source§impl Serialize for WorkspaceDiagnosticKind
impl Serialize for WorkspaceDiagnosticKind
Source§fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
impl StructuralPartialEq for WorkspaceDiagnosticKind
Auto Trait Implementations§
impl Freeze for WorkspaceDiagnosticKind
impl RefUnwindSafe for WorkspaceDiagnosticKind
impl Send for WorkspaceDiagnosticKind
impl Sync for WorkspaceDiagnosticKind
impl Unpin for WorkspaceDiagnosticKind
impl UnsafeUnpin for WorkspaceDiagnosticKind
impl UnwindSafe for WorkspaceDiagnosticKind
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<D> OwoColorize for D
impl<D> OwoColorize for D
Source§fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
fn fg<C>(&self) -> FgColorDisplay<'_, C, Self>where
C: Color,
Source§fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
fn bg<C>(&self) -> BgColorDisplay<'_, C, Self>where
C: Color,
Source§fn black(&self) -> FgColorDisplay<'_, Black, Self>
fn black(&self) -> FgColorDisplay<'_, Black, Self>
Source§fn on_black(&self) -> BgColorDisplay<'_, Black, Self>
fn on_black(&self) -> BgColorDisplay<'_, Black, Self>
Source§fn red(&self) -> FgColorDisplay<'_, Red, Self>
fn red(&self) -> FgColorDisplay<'_, Red, Self>
Source§fn on_red(&self) -> BgColorDisplay<'_, Red, Self>
fn on_red(&self) -> BgColorDisplay<'_, Red, Self>
Source§fn green(&self) -> FgColorDisplay<'_, Green, Self>
fn green(&self) -> FgColorDisplay<'_, Green, Self>
Source§fn on_green(&self) -> BgColorDisplay<'_, Green, Self>
fn on_green(&self) -> BgColorDisplay<'_, Green, Self>
Source§fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>
fn yellow(&self) -> FgColorDisplay<'_, Yellow, Self>
Source§fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>
fn on_yellow(&self) -> BgColorDisplay<'_, Yellow, Self>
Source§fn blue(&self) -> FgColorDisplay<'_, Blue, Self>
fn blue(&self) -> FgColorDisplay<'_, Blue, Self>
Source§fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>
fn on_blue(&self) -> BgColorDisplay<'_, Blue, Self>
Source§fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>
fn magenta(&self) -> FgColorDisplay<'_, Magenta, Self>
Source§fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>
fn on_magenta(&self) -> BgColorDisplay<'_, Magenta, Self>
Source§fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>
fn purple(&self) -> FgColorDisplay<'_, Magenta, Self>
Source§fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>
fn on_purple(&self) -> BgColorDisplay<'_, Magenta, Self>
Source§fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>
fn cyan(&self) -> FgColorDisplay<'_, Cyan, Self>
Source§fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>
fn on_cyan(&self) -> BgColorDisplay<'_, Cyan, Self>
Source§fn white(&self) -> FgColorDisplay<'_, White, Self>
fn white(&self) -> FgColorDisplay<'_, White, Self>
Source§fn on_white(&self) -> BgColorDisplay<'_, White, Self>
fn on_white(&self) -> BgColorDisplay<'_, White, Self>
Source§fn default_color(&self) -> FgColorDisplay<'_, Default, Self>
fn default_color(&self) -> FgColorDisplay<'_, Default, Self>
Source§fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>
fn on_default_color(&self) -> BgColorDisplay<'_, Default, Self>
Source§fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>
fn bright_black(&self) -> FgColorDisplay<'_, BrightBlack, Self>
Source§fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>
fn on_bright_black(&self) -> BgColorDisplay<'_, BrightBlack, Self>
Source§fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>
fn bright_red(&self) -> FgColorDisplay<'_, BrightRed, Self>
Source§fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>
fn on_bright_red(&self) -> BgColorDisplay<'_, BrightRed, Self>
Source§fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>
fn bright_green(&self) -> FgColorDisplay<'_, BrightGreen, Self>
Source§fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>
fn on_bright_green(&self) -> BgColorDisplay<'_, BrightGreen, Self>
Source§fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>
fn bright_yellow(&self) -> FgColorDisplay<'_, BrightYellow, Self>
Source§fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>
fn on_bright_yellow(&self) -> BgColorDisplay<'_, BrightYellow, Self>
Source§fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>
fn bright_blue(&self) -> FgColorDisplay<'_, BrightBlue, Self>
Source§fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>
fn on_bright_blue(&self) -> BgColorDisplay<'_, BrightBlue, Self>
Source§fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
fn bright_magenta(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
Source§fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
fn on_bright_magenta(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
Source§fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
fn bright_purple(&self) -> FgColorDisplay<'_, BrightMagenta, Self>
Source§fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
fn on_bright_purple(&self) -> BgColorDisplay<'_, BrightMagenta, Self>
Source§fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>
fn bright_cyan(&self) -> FgColorDisplay<'_, BrightCyan, Self>
Source§fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>
fn on_bright_cyan(&self) -> BgColorDisplay<'_, BrightCyan, Self>
Source§fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>
fn bright_white(&self) -> FgColorDisplay<'_, BrightWhite, Self>
Source§fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>
fn on_bright_white(&self) -> BgColorDisplay<'_, BrightWhite, Self>
Source§fn bold(&self) -> BoldDisplay<'_, Self>
fn bold(&self) -> BoldDisplay<'_, Self>
Source§fn dimmed(&self) -> DimDisplay<'_, Self>
fn dimmed(&self) -> DimDisplay<'_, Self>
Source§fn italic(&self) -> ItalicDisplay<'_, Self>
fn italic(&self) -> ItalicDisplay<'_, Self>
Source§fn underline(&self) -> UnderlineDisplay<'_, Self>
fn underline(&self) -> UnderlineDisplay<'_, Self>
Source§fn blink(&self) -> BlinkDisplay<'_, Self>
fn blink(&self) -> BlinkDisplay<'_, Self>
Source§fn blink_fast(&self) -> BlinkFastDisplay<'_, Self>
fn blink_fast(&self) -> BlinkFastDisplay<'_, Self>
Source§fn reversed(&self) -> ReversedDisplay<'_, Self>
fn reversed(&self) -> ReversedDisplay<'_, Self>
Source§fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>
fn strikethrough(&self) -> StrikeThroughDisplay<'_, Self>
Source§fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn color<Color>(&self, color: Color) -> FgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
OwoColorize::fg or
a color-specific method, such as OwoColorize::green, Read moreSource§fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
fn on_color<Color>(&self, color: Color) -> BgDynColorDisplay<'_, Color, Self>where
Color: DynColor,
OwoColorize::bg or
a color-specific method, such as OwoColorize::on_yellow, Read more