S26: Hallucinated crate, API, or feature flag
What it looks like
Section titled “What it looks like”There are three forms. The first two do not compile:
let tags = vec!["rust", "java", "rust"];let unique = tags.unique(); // error E0599: no method named `unique` found for `Vec<&str>`unique() is not a method of Vec or of the standard Iterator. It is a method of the itertools crate, so the agent mixed up two APIs.
use csv_fast_reader::read_rows; // error E0432: unresolved import `csv_fast_reader`There is no crate with this name on crates.io. If the agent also adds it to Cargo.toml, cargo build fails with “no matching package named csv_fast_reader found”.
The third form is the dangerous one. It compiles:
/// "Removes duplicate tags." It compiles, but `dedup` removes only/// duplicates that are next to each other.pub fn unique_tags(mut tags: Vec<String>) -> Vec<String> { tags.dedup(); tags}dedup is real, but it removes only duplicates that are next to each other. For ["rust", "java", "rust"] it removes nothing. The test worse_keeps_duplicates_that_are_not_adjacent shows it.
Why AI agents produce it
Section titled “Why AI agents produce it”- A name that sounds right. Agents produce plausible names: a method that “should” exist, or a crate named like a well-known one with a suffix.
- APIs change. A method that existed in an old version of a crate, or was renamed, is still in the training data.
- Methods from extension traits.
itertools,futures, andtokioadd methods to standard types through traits. In code that imports them,.unique()works. In code that does not, it does not exist. - Feature flags. Many crates hide parts of the API behind features, such as
serde’sderiveortokio’srt-multi-thread. Agents invent feature names, or forget the feature that an API needs.
Why it is a problem
Section titled “Why it is a problem”- Code that does not compile is cheap. The compiler finds it at once. But an agent that “fixes” the error may guess again, or add a crate to make the name exist.
- A crate name that does not exist today can exist tomorrow. Attackers register crate names that agents tend to invent (“slopsquatting”). Then the build succeeds, and runs the attacker’s code. Check each new dependency on crates.io.
- A real method with the wrong meaning compiles and passes simple tests.
dedupon already sorted test data gives the expected result. This is the version that reaches production.
The better version
Section titled “The better version”Worse
dedup, which removes only adjacent duplicates. The doc comment promises more./// "Removes duplicate tags." It compiles, but `dedup` removes only/// duplicates that are next to each other.pub fn unique_tags(mut tags: Vec<String>) -> Vec<String> {tags.dedup();tags}BetterA
HashSetof seen tags. Removes all duplicates and keeps the first of each, in order./// Removes duplicate tags and keeps the first occurrence of each, in order.pub fn unique_tags(tags: Vec<String>) -> Vec<String> {let mut seen = HashSet::new();tags.into_iter().filter(|tag| seen.insert(tag.clone())) // `insert` returns false for a duplicate.collect()}
The better version uses only the standard library, and a test with a duplicate that is not adjacent proves that it does what the doc comment says.
When it is acceptable
Section titled “When it is acceptable”Never. But a method that you do not know is not always invented. Many real methods are new or rare. Check before you reject it.
How to detect it
Section titled “How to detect it”- Run the build.
cargo checkfinds every invented method, type, and import. Never review agent code that you have not compiled. - Look up each method that you do not know on docs.rs for the crate and version in
Cargo.lock. Check what it does, not only that it exists. - For each new crate in
Cargo.toml, open its crates.io page. Check the name exactly, the downloads, the repository link, and the last release. See S28: Too many or unknown dependencies. - For each feature flag, check the crate’s feature list on docs.rs or in its
Cargo.toml. - Ask for a test with input that tells the right meaning from the wrong one: here, a duplicate that is not adjacent.
What to tell your agent
Section titled “What to tell your agent”Use only APIs that exist in the crate versions in Cargo.lock. For each methodor crate you are not sure about, check docs.rs and say which page you used.Do not add a new dependency to make a name compile. Add a test whose inputshows that the code does what its doc comment says, including the edgecases. Run cargo check and cargo test.Related: S28: Too many or unknown dependencies, S27: Outdated idioms (try!, extern crate, lazy_static, old edition), and Modules, crates, and Cargo.