<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mykhailo</title>
    <description>The latest articles on DEV Community by Mykhailo (@yetmike).</description>
    <link>https://dev.to/yetmike</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3901143%2F338ae527-f75c-4c2d-846c-358209ca021f.jpg</url>
      <title>DEV Community: Mykhailo</title>
      <link>https://dev.to/yetmike</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yetmike"/>
    <language>en</language>
    <item>
      <title>The 22 Rust errors every beginner hits, in the order they hit them</title>
      <dc:creator>Mykhailo</dc:creator>
      <pubDate>Sun, 16 Aug 2026 20:50:35 +0000</pubDate>
      <link>https://dev.to/yetmike/the-22-rust-errors-every-beginner-hits-in-the-order-they-hit-them-13gi</link>
      <guid>https://dev.to/yetmike/the-22-rust-errors-every-beginner-hits-in-the-order-they-hit-them-13gi</guid>
      <description>&lt;p&gt;Rust's compiler is the best teacher in the language and almost nobody reads it properly. Below are the 22 errors you will actually hit, roughly in the order you'll hit them, with what each one is really telling you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Every diagnostic here is real.&lt;/strong&gt; It was captured from a real rustc 1.96.0 (ac68faa20 2026-05-25) compiling a real broken program. The explanations were drafted with an LLM and edited by me.&lt;/p&gt;

&lt;p&gt;Two things to know before the list.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Most Rust errors underline two places.&lt;/strong&gt; One is where the rule was broken. The other is where the decision that broke it was made. The error is reported at the first; the fix is almost always at the second.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The &lt;code&gt;help:&lt;/code&gt; block is often a literal diff.&lt;/strong&gt; When you see &lt;code&gt;+++&lt;/code&gt; under a span, rustc isn't describing the fix. It's writing it.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. E0061: The function takes two arguments and you passed one.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0061]: this function takes 2 arguments but 1 argument was supplied
 --&amp;gt; src/main.rs:6:20
  |
6 |     println!("{}", add(1));
  |                    ^^^--- argument #2 of type `i32` is missing
  |
note: function defined here
 --&amp;gt; src/main.rs:1:4
  |
1 | fn add(a: i32, b: i32) -&amp;gt; i32 {
  |    ^^^         ------
help: provide the argument
  |
6 |     println!("{}", add(1, /* i32 */));
  |                         +++++++++++
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The fix.&lt;/strong&gt; Pass both: &lt;code&gt;add(1, 2)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Rust has no default parameters and no overloading, so arity is exact. That sounds restrictive until you notice it means a function signature is a complete description of how to call it. There is never a hidden second way.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. E0277: &lt;code&gt;Vec&lt;/code&gt; has no single obvious way to print itself, so &lt;code&gt;{}&lt;/code&gt; will not take it.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0277]: `Vec&amp;lt;{integer}&amp;gt;` doesn't implement `std::fmt::Display`
 --&amp;gt; src/main.rs:3:20
  |
3 |     println!("{}", numbers);
  |               --   ^^^^^^^ `Vec&amp;lt;{integer}&amp;gt;` cannot be formatted with the default formatter
  |               |
  |               required by this formatting parameter
  |
  = help: the trait `std::fmt::Display` is not implemented for `Vec&amp;lt;{integer}&amp;gt;`
  = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The fix.&lt;/strong&gt; Use the debug formatter: &lt;code&gt;println!("{:?}", numbers);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is the first trait error most people meet, and the message names the exact missing capability: &lt;code&gt;Vec&amp;lt;i32&amp;gt; doesn't implement std::fmt::Display&lt;/code&gt;. Read trait errors as a sentence (this type cannot do that thing) rather than as a wall.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. E0282: Rust cannot work out what type this collection holds, because nothing was ever put in it.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0282]: type annotations needed for `Vec&amp;lt;_&amp;gt;`
 --&amp;gt; src/main.rs:2:9
  |
2 |     let items = Vec::new();
  |         ^^^^^   ---------- type must be known at this point
  |
help: consider giving `items` an explicit type, where the type for type parameter `T` is specified
  |
2 |     let items: Vec&amp;lt;T&amp;gt; = Vec::new();
  |              ++++++++
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The fix.&lt;/strong&gt; Say it: &lt;code&gt;let items: Vec&amp;lt;i32&amp;gt; = Vec::new();&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Rust infers types from &lt;em&gt;use&lt;/em&gt;, not from declaration. Push one integer and the annotation becomes unnecessary, because the inference works forward from evidence, and here you gave it none.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. E0308: You promised an &lt;code&gt;i32&lt;/code&gt; and returned nothing.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0308]: mismatched types
 --&amp;gt; src/main.rs:1:14
  |
1 | fn five() -&amp;gt; i32 {
  |    ----      ^^^ expected `i32`, found `()`
  |    |
  |    implicitly returns `()` as its body has no tail or `return` expression
2 |     5;
  |      - help: remove this semicolon to return this value
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The fix.&lt;/strong&gt; Delete the semicolon after &lt;code&gt;5&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;()&lt;/code&gt; is Rust's word for "nothing". Whenever you see &lt;code&gt;found ()&lt;/code&gt;, look for a stray semicolon before you look at anything else. In Rust an expression without a semicolon &lt;em&gt;is&lt;/em&gt; the value, and with one it becomes a statement that evaluates to nothing.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. E0381: The variable was declared but never given a value, and you read it.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0381]: used binding `count` isn't initialized
 --&amp;gt; src/main.rs:3:16
  |
2 |     let count: i32;
  |         ----- binding declared here but left uninitialized
3 |     println!("{count}");
  |                ^^^^^ `count` used here but it isn't initialized
  |
help: consider assigning a value
  |
2 |     let count: i32 = 42;
  |                    ++++
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The fix.&lt;/strong&gt; Give it a value: &lt;code&gt;let count: i32 = 0;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Other languages hand you a zero or a null here. Rust refuses to guess, and that refusal is the point: there is no such thing as an uninitialised read in safe Rust, so a whole category of bug cannot reach runtime.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. E0384: &lt;code&gt;let&lt;/code&gt; bindings do not change unless you say &lt;code&gt;mut&lt;/code&gt;.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0384]: cannot assign twice to immutable variable `x`
 --&amp;gt; src/main.rs:3:5
  |
2 |     let x = 5;
  |         - first assignment to `x`
3 |     x = 6;
  |     ^^^^^ cannot assign twice to immutable variable
  |
help: consider making this binding mutable
  |
2 |     let mut x = 5;
  |         +++
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The fix.&lt;/strong&gt; Write &lt;code&gt;let mut x = 5;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Two spans, not one: the &lt;code&gt;^^^^^&lt;/code&gt; is where the rule broke, the &lt;code&gt;-&lt;/code&gt; marks where the decision was made. The error is reported at the assignment, the thing you change is the declaration. That pattern holds across most Rust errors, and once you see it you cannot unsee it.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. E0425: You used a name that was never declared in this scope.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0425]: cannot find value `count` in this scope
 --&amp;gt; src/main.rs:2:20
  |
2 |     println!("{}", count);
  |                    ^^^^^ not found in this scope
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The fix.&lt;/strong&gt; Declare it first: &lt;code&gt;let count = 0;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Ninety percent of the time this is a typo, and rustc will often guess the name you meant in a &lt;code&gt;help:&lt;/code&gt; line. Read that before you go looking for a real bug, because the compiler has already done the search.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. E0596: You called a method that needs to modify the value, on a binding that cannot be modified.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0596]: cannot borrow `numbers` as mutable, as it is not declared as mutable
 --&amp;gt; src/main.rs:3:5
  |
3 |     numbers.push(4);
  |     ^^^^^^^ cannot borrow as mutable
  |
help: consider changing this to be mutable
  |
2 |     let mut numbers = vec![1, 2, 3];
  |         +++
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The fix.&lt;/strong&gt; &lt;code&gt;let mut numbers = vec![1, 2, 3];&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The interesting part is that &lt;code&gt;push&lt;/code&gt; never says "mutable" in your code; you have to know its signature takes &lt;code&gt;&amp;amp;mut self&lt;/code&gt;. The compiler is telling you a fact about a function you did not write, which is why the fix is on a different line from the error.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. E0599: That type has no such method.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0599]: no method named `push` found for type `{integer}` in the current scope
 --&amp;gt; src/main.rs:3:11
  |
3 |     count.push(1);
  |           ^^^^ method not found in `{integer}`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The fix.&lt;/strong&gt; Use a type that has it, or the right method for this one.&lt;/p&gt;

&lt;p&gt;When the type is right but the method is missing, rustc often lists candidates with similar names, and sometimes tells you a trait exists but is not in scope, which is a &lt;code&gt;use&lt;/code&gt; statement away, not a redesign.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. E0601: Every Rust program starts at a function called &lt;code&gt;main&lt;/code&gt;, and there isn't one.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0601]: `main` function not found in crate `snippet`
 --&amp;gt; src/main.rs:3:2
  |
3 | }
  |  ^ consider adding a `main` function to src/main.rs`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The fix.&lt;/strong&gt; Rename the function to &lt;code&gt;main&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The compiler is not looking for your code, it is looking for one specific name. Rust has no "top level" that runs. The entry point is a convention with no flexibility, and this is usually the first time a beginner learns the program has a designated front door.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. E0618: You put call parentheses after something that is not a function.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0618]: expected function, found `{integer}`
 --&amp;gt; src/main.rs:3:18
  |
2 |     let total = 5;
  |         ----- `total` has type `{integer}`
3 |     let result = total();
  |                  ^^^^^--
  |                  |
  |                  call expression requires function
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The fix.&lt;/strong&gt; Drop the parentheses, or call the function you meant.&lt;/p&gt;

&lt;p&gt;Usually a shadowed name: a variable and a function with the same identifier, and the variable won. The &lt;code&gt;help:&lt;/code&gt; line will tell you what the thing actually is, which is faster than re-reading your own code.&lt;/p&gt;

&lt;h2&gt;
  
  
  12. E0765: A string was opened with a quote and never closed.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0765]: unterminated double quote string
 --&amp;gt; src/main.rs:3:25
  |
3 |       println!("{greeting}");
  |  _________________________^
4 | | }
  | |_^
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The fix.&lt;/strong&gt; Close the quote: &lt;code&gt;let greeting = "hello";&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Notice the error points at where the string &lt;em&gt;started&lt;/em&gt;, not where the compiler gave up. That is the general pattern for unclosed things: the reported line is the opening, because the compiler cannot know which of the following lines you meant to close it on.&lt;/p&gt;

&lt;h2&gt;
  
  
  13. E0004: A &lt;code&gt;match&lt;/code&gt; has to cover every possible case and yours misses one.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0004]: non-exhaustive patterns: `Direction::South` not covered
  --&amp;gt; src/main.rs:8:11
   |
 8 |     match d {
   |           ^ pattern `Direction::South` not covered
   |
note: `Direction` defined here
  --&amp;gt; src/main.rs:1:6
   |
 1 | enum Direction {
   |      ^^^^^^^^^
 2 |     North,
 3 |     South,
   |     ----- not covered
   = note: the matched value is of type `Direction`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
   |
 9 ~         Direction::North =&amp;gt; println!("up"),
10 ~         Direction::South =&amp;gt; todo!(),
   |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The fix.&lt;/strong&gt; Add the missing arm, or a &lt;code&gt;_ =&amp;gt; {}&lt;/code&gt; catch-all.&lt;/p&gt;

&lt;p&gt;This is the feature you will miss most in other languages. Add a variant to the enum a year later and every match that forgot to handle it fails to compile. The compiler maintains your switch statements for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  14. E0005: That pattern can fail, and &lt;code&gt;let&lt;/code&gt; has nowhere to go when it does.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0005]: refutable pattern in local binding
 --&amp;gt; src/main.rs:3:9
  |
3 |     let Some(value) = maybe;
  |         ^^^^^^^^^^^ pattern `None` not covered
  |
  = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
  = note: for more information, visit https://doc.rust-lang.org/book/ch19-02-refutability.html
  = note: the matched value is of type `Option&amp;lt;i32&amp;gt;`
help: you might want to use `let...else` to handle the variant that isn't matched
  |
3 |     let Some(value) = maybe else { todo!() };
  |                             ++++++++++++++++
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The fix.&lt;/strong&gt; Use &lt;code&gt;if let Some(value) = maybe { … }&lt;/code&gt; or &lt;code&gt;let Some(value) = maybe else { … };&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;let&lt;/code&gt; must always succeed, so it only accepts patterns that cannot fail. This is where &lt;code&gt;if let&lt;/code&gt; and &lt;code&gt;let … else&lt;/code&gt; come from: they are the versions with somewhere to put the failure.&lt;/p&gt;

&lt;h2&gt;
  
  
  15. E0063: You built a struct without all of its fields.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0063]: missing field `y` in initializer of `Point`
 --&amp;gt; src/main.rs:7:13
  |
7 |     let p = Point { x: 1 };
  |             ^^^^^ missing `y`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The fix.&lt;/strong&gt; Supply &lt;code&gt;y&lt;/code&gt; too.&lt;/p&gt;

&lt;p&gt;There is no partially-built struct in Rust. Every field is set at construction or the value does not exist, which is why you never have to check whether a field was initialised.&lt;/p&gt;

&lt;h2&gt;
  
  
  16. E0070: The left side of &lt;code&gt;=&lt;/code&gt; has to be something that can be assigned to.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0070]: invalid left-hand side of assignment
 --&amp;gt; src/main.rs:2:7
  |
2 |     5 = 6;
  |     - ^
  |     |
  |     cannot assign to this expression
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The fix.&lt;/strong&gt; Assign to a variable, or use &lt;code&gt;==&lt;/code&gt; if you meant to compare.&lt;/p&gt;

&lt;p&gt;Almost always a &lt;code&gt;==&lt;/code&gt; typed as &lt;code&gt;=&lt;/code&gt;. In C this class of typo silently compiles inside an &lt;code&gt;if&lt;/code&gt;; Rust rejects it because a condition must be a &lt;code&gt;bool&lt;/code&gt; and an assignment is not one.&lt;/p&gt;

&lt;h2&gt;
  
  
  17. E0382: The value moved to a new owner, and you used the old name afterwards.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0382]: borrow of moved value: `name`
 --&amp;gt; src/main.rs:4:16
  |
2 |     let name = String::from("crab");
  |         ---- move occurs because `name` has type `String`, which does not implement the `Copy` trait
3 |     let other = name;
  |                 ---- value moved here
4 |     println!("{name}");
  |                ^^^^ value borrowed here after move
  |
help: consider cloning the value if the performance cost is acceptable
  |
3 |     let other = name.clone();
  |                     ++++++++
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The fix.&lt;/strong&gt; Clone it, or borrow with &lt;code&gt;&amp;amp;name&lt;/code&gt;, or use &lt;code&gt;other&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Read the &lt;code&gt;note:&lt;/code&gt; rather than the error: &lt;em&gt;move occurs because &lt;code&gt;String&lt;/code&gt; does not implement the &lt;code&gt;Copy&lt;/code&gt; trait&lt;/em&gt;. That single line is the whole ownership model. An &lt;code&gt;i32&lt;/code&gt; in the same code would have been fine, because copying eight bytes is free and copying a heap allocation is not.&lt;/p&gt;

&lt;h2&gt;
  
  
  18. E0423: You used a struct's name where a value was expected.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0423]: expected value, found struct `Config`
 --&amp;gt; src/main.rs:6:13
  |
1 | / struct Config {
2 | |     debug: bool,
3 | | }
  | |_- `Config` defined here
...
6 |       let c = Config;
  |               ^^^^^^ help: use struct literal syntax instead: `Config { debug: val }`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The fix.&lt;/strong&gt; Construct it: &lt;code&gt;Config { debug: true }&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A struct name is a type, not a value, unless it is a unit struct, in which case the name &lt;em&gt;is&lt;/em&gt; the value. That inconsistency is real and worth knowing, and the error message tells you which case you are in.&lt;/p&gt;

&lt;h2&gt;
  
  
  19. E0428: Two things with the same name in the same scope.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0428]: the name `total` is defined multiple times
 --&amp;gt; src/main.rs:5:1
  |
1 | fn total() -&amp;gt; i32 {
  | ----------------- previous definition of the value `total` here
...
5 | fn total() -&amp;gt; i32 {
  | ^^^^^^^^^^^^^^^^^ `total` redefined here
  |
  = note: `total` must be defined only once in the value namespace of this module
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The fix.&lt;/strong&gt; Rename one of them.&lt;/p&gt;

&lt;p&gt;No overloading in Rust: one name, one item, per scope. This is the language deciding that "which one did I call?" should never be a question you have to answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  20. E0432: The path in your &lt;code&gt;use&lt;/code&gt; statement does not exist.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0432]: unresolved import `std::collections::HashMapp`
 --&amp;gt; src/main.rs:1:5
  |
1 | use std::collections::HashMapp;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ no `HashMapp` in `collections`
  |
help: a similar name exists in the module
  |
1 - use std::collections::HashMapp;
1 + use std::collections::HashMap;
  |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The fix.&lt;/strong&gt; Fix the spelling: &lt;code&gt;HashMap&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Import errors surface before type errors, so a single typo in a &lt;code&gt;use&lt;/code&gt; line can produce a cascade of unrelated-looking failures below it. Always fix the topmost error first and recompile. Most of the rest often vanish.&lt;/p&gt;

&lt;h2&gt;
  
  
  21. E0433: The type exists in the standard library but has not been brought into scope.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0433]: cannot find type `HashMap` in this scope
 --&amp;gt; src/main.rs:2:18
  |
2 |     let scores = HashMap::new();
  |                  ^^^^^^^ use of undeclared type `HashMap`
  |
help: consider importing this struct
  |
1 + use std::collections::HashMap;
  |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The fix.&lt;/strong&gt; &lt;code&gt;use std::collections::HashMap;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Rust's prelude is deliberately tiny: only the handful of items nearly every program needs. Everything else you import by hand, and rustc will usually print the exact &lt;code&gt;use&lt;/code&gt; line, which you can paste.&lt;/p&gt;

&lt;h2&gt;
  
  
  22. E0609: That struct has no field by that name.
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;error[E0609]: no field `z` on type `Point`
 --&amp;gt; src/main.rs:8:22
  |
8 |     println!("{}", p.z);
  |                      ^ unknown field
  |
help: a field with a similar name exists
  |
8 -     println!("{}", p.z);
8 +     println!("{}", p.x);
  |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The fix.&lt;/strong&gt; Use a field that exists, or add it to the struct.&lt;/p&gt;

&lt;p&gt;rustc lists the fields that do exist, which makes this one of the errors you can fix without leaving the terminal. Worth noticing: the available-fields list is the compiler volunteering information you did not ask for.&lt;/p&gt;




&lt;h2&gt;
  
  
  The pattern behind all of them
&lt;/h2&gt;

&lt;p&gt;Once you've read a few hundred of these, they stop being 22 separate errors and become four questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Who owns this value, and did I give it away?&lt;/strong&gt; Ownership errors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How long does this reference need to live?&lt;/strong&gt; Lifetime errors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Does this type do the thing I'm asking of it?&lt;/strong&gt; Trait errors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Did I say what I meant?&lt;/strong&gt; Type, scope and mutability errors.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's the language's whole difficulty curve, and the compiler tells you which of the four you're in every single time.&lt;/p&gt;




&lt;p&gt;If you want to practise these against a real compiler without installing anything, that's what I built codecrab for: actual &lt;code&gt;rustc&lt;/code&gt; output, the failing span underlined in your own source, one hint at a time. 94 exercises. Exercises derive from rustlings (MIT).&lt;/p&gt;

&lt;p&gt;There'll be a paid tier later, chapters 6 and up, because compiling costs real money and I'd like this to still exist in 2028. Anyone with an account before that ships keeps the whole course.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codecrab.app/" rel="noopener noreferrer"&gt;https://codecrab.app/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>beginners</category>
      <category>learning</category>
      <category>programming</category>
    </item>
    <item>
      <title>Forward Deployed Engineer is outsourcing with a better logo</title>
      <dc:creator>Mykhailo</dc:creator>
      <pubDate>Fri, 14 Aug 2026 00:26:41 +0000</pubDate>
      <link>https://dev.to/yetmike/forward-deployed-engineer-is-outsourcing-with-a-better-logo-3o55</link>
      <guid>https://dev.to/yetmike/forward-deployed-engineer-is-outsourcing-with-a-better-logo-3o55</guid>
      <description>&lt;p&gt;I spent more than five years in outsourcing companies. That is where I started my career.&lt;/p&gt;

&lt;p&gt;The job looked like this: get assigned to a client, learn their infrastructure, fight their legacy systems, sit in calls with people who could not describe what they wanted, ship something that worked, move to the next client. Sometimes I was on their VPN more than my own employer's. Sometimes I knew their systems better than their own staff did.&lt;/p&gt;

&lt;p&gt;Now the same job has a new name and a salary that can be twice as high. It is called Forward Deployed Engineer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the name came from
&lt;/h2&gt;

&lt;p&gt;The term belongs to &lt;a href="https://en.wikipedia.org/wiki/Palantir_Technologies" rel="noopener noreferrer"&gt;Palantir&lt;/a&gt;. The earliest published use I could find is a &lt;a href="https://techcrunch.com/2010/06/25/palantir-the-next-billion-dollar-company-raises-90-million/" rel="noopener noreferrer"&gt;TechCrunch piece from June 2010&lt;/a&gt; about a funding round, which identifies one of their employees by the title forward deployed engineer.&lt;/p&gt;

&lt;p&gt;The name is borrowed from the military, where a &lt;a href="https://en.wikipedia.org/wiki/Forward_operating_base" rel="noopener noreferrer"&gt;forward deployed&lt;/a&gt; unit sits in the field instead of at home base. That is the whole idea. Palantir was selling &lt;a href="https://en.wikipedia.org/wiki/Data_integration" rel="noopener noreferrer"&gt;data integration&lt;/a&gt; software to intelligence and defense customers who could not describe what they needed, partly because the requirements were classified and partly because nobody had written them down. Shipping the software did not work. So they shipped engineers, cleared and embedded on site, writing production code inside the customer's environment for months at a time.&lt;/p&gt;

&lt;p&gt;Internally Palantir called them Deltas, a name they explain in their own post on &lt;a href="https://blog.palantir.com/dev-versus-delta-demystifying-engineering-roles-at-palantir-ad44c2a6e87" rel="noopener noreferrer"&gt;Dev versus Delta&lt;/a&gt;. According to &lt;a href="https://newsletter.pragmaticengineer.com/p/forward-deployed-engineers" rel="noopener noreferrer"&gt;The Pragmatic Engineer&lt;/a&gt;, the company had more FDEs than regular software engineers until roughly 2016. That is a striking ratio for a company that sells a product. There is also &lt;a href="https://blog.palantir.com/a-day-in-the-life-of-a-palantir-forward-deployed-software-engineer-45ef2de257b1" rel="noopener noreferrer"&gt;a day in the life of an FDE&lt;/a&gt; from 2022 if you want their version of the job.&lt;/p&gt;

&lt;p&gt;So the name is about fifteen years old, and the current wave of AI companies hiring FDEs did not invent anything. They picked up a label that already had a decade of history and a good story attached to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The job description is identical
&lt;/h2&gt;

&lt;p&gt;Read what an FDE is supposed to do. Integrate a vendor's product with the client's messy data. Build custom pipelines and workflows on top of it. Sit with non-technical stakeholders and translate business pain into technical requirements. Feed real-world edge cases back to the product team.&lt;/p&gt;

&lt;p&gt;Now read what I did in outsourcing. Integrate whatever the client bought with whatever the client already had. Build custom pipelines on top of it. Sit with non-technical stakeholders and translate business pain into technical requirements. File bugs and feature requests upstream when the vendor's product could not do the thing the client paid for.&lt;/p&gt;

&lt;p&gt;I cannot find the daily difference. Same messy enterprise APIs. Same undocumented internal system that one person understands and that person is on vacation. Same client stakeholder who changes the requirement after the sprint started. Same travel, same context switching, same burnout curve.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwbdy28k56an4zxk89qhm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwbdy28k56an4zxk89qhm.png" alt="Scooby-Doo unmasking meme: the masked figure is labelled Forward Deployed Engineer, and underneath the mask is an outsource engineer on twice the pay" width="600" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually differs
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpuxws8qdq33778w13m1j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpuxws8qdq33778w13m1j.png" alt="Outsourcing agency sells hours and locks the client into people; a product vendor sells licenses and locks the client into the platform. Same engineer, same messy APIs, up to twice the pay" width="800" height="600"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Two business models, one job description.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;An outsourcing agency sells hours. The unit of revenue is a person occupying a seat for a month. If a client cuts ten engineers, the agency loses ten engineers of revenue. Every engineer is a line item, and line items get negotiated down. That is why the rate is what it is, and it is why the agency's incentive is to keep bodies billable rather than to make any single engineer irreplaceable.&lt;/p&gt;

&lt;p&gt;A product vendor sells licenses. The unit of revenue is an annual contract with a margin an agency will never see. The engineer they send into the client is not the product. The engineer is what makes the contract renew. One person who unblocks a stuck rollout can be the reason a seven-figure renewal happens instead of a churn. That is a very different number to justify a salary against.&lt;/p&gt;

&lt;p&gt;If you want the numbers, &lt;a href="https://www.levels.fyi/" rel="noopener noreferrer"&gt;levels.fyi&lt;/a&gt; has them. Palantir's forward deployed software engineer sits around $211K median. An &lt;a href="https://www.levels.fyi/companies/epam-systems/salaries/software-engineer/locations/united-states" rel="noopener noreferrer"&gt;EPAM engineer in the US&lt;/a&gt; is $165K. &lt;a href="https://www.levels.fyi/companies/accenture/salaries/software-engineer/locations/united-states" rel="noopener noreferrer"&gt;Accenture&lt;/a&gt; is closer to $109K. The frontier labs pay far more than any of them, but they pay everyone far more, so that gap is the company and not the title.&lt;/p&gt;

&lt;h2&gt;
  
  
  The lock-in argument does not hold up
&lt;/h2&gt;

&lt;p&gt;The usual defense is that outsourcing and FDE work create different kinds of dependency. Outsourcing locks the client into people who understand the custom code. FDE work locks the client into the vendor's platform.&lt;/p&gt;

&lt;p&gt;Both are &lt;a href="https://en.wikipedia.org/wiki/Vendor_lock-in" rel="noopener noreferrer"&gt;lock-in&lt;/a&gt;. I have watched both happen. I have written the pipeline that nobody else could maintain, and I have also been the one who inherited someone else's version of it three years later and needed two weeks just to draw the diagram.&lt;/p&gt;

&lt;p&gt;The distinction people draw is real but small. It describes who captures the value, not what the engineer does with their day. An engineer wiring a client's legacy database into a vendor's domain model is doing the same work whether the invoice says &lt;a href="https://en.wikipedia.org/wiki/Time_and_materials" rel="noopener noreferrer"&gt;time and materials&lt;/a&gt; or annual license.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I would actually tell someone trying to make the jump
&lt;/h2&gt;

&lt;p&gt;If you are in outsourcing and you want the FDE title and the FDE compensation, the honest advice is to stop optimizing your engineering and start optimizing three other things.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learn one product deeply instead of ten stacks shallowly.&lt;/strong&gt; Outsourcing rewards breadth. You get thrown at whatever the next contract needs, and after five years you have touched a dozen stacks and mastered none of them. Product companies hire for the opposite. They want someone who knows their platform's data model well enough to argue with the core team about it. Pick a platform, go deep, get certified if the vendor offers it, build something real on it in public.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Get comfortable being wrong in front of executives.&lt;/strong&gt; In outsourcing my escalation path was almost always internal. There was an account manager and a delivery lead between me and anyone who owned a budget. FDE work removes those layers. You are in the room where the customer decides whether to keep paying, and you have to say "that integration will take three weeks and here is why" to someone who wanted to hear one week.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Go find out what they are actually hiring for.&lt;/strong&gt; Change your LinkedIn title to Forward Deployed Engineer and start reading the job posts. Scrape them if you want, there is nothing hidden here. A few dozen descriptions will tell you what the requirements really are, and once you line them up against your own CV the gaps are obvious. Then build a plan to close them.&lt;/p&gt;

&lt;p&gt;What you will notice is that almost every one of these roles is at a product company. So you need a product mindset. Not just "solve the client's problem", but understand why the company put you at this particular client, what that account means to them, and what happens if it goes badly.&lt;/p&gt;

&lt;p&gt;None of this is about writing better code. If you are already the person the client asks for by name, you have the engineering part.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part I am not sure about
&lt;/h2&gt;

&lt;p&gt;I do not know how durable the FDE label is. Roles that exist to make a specific product land tend to get squeezed when the product gets easier to deploy, or when the vendor decides the work belongs to a partner network. That is more or less what happened to a lot of specialist consulting niches over the last decade.&lt;/p&gt;

&lt;p&gt;I also do not know whether the pay gap survives the title becoming common. Right now it is scarce enough that the compensation reflects the revenue it protects. In five years there may be a lot of people with FDE on their profile, and the salary may look a lot more like a senior engineer's, and the same people who chased the title will be looking for the next one.&lt;/p&gt;

&lt;p&gt;I did this job for five years before it had the good name. Nobody called it strategic then, and I still cannot tell whether they were wrong about the work or just early on the pricing.&lt;/p&gt;




&lt;p&gt;Originally published on &lt;a href="https://yetmike.com/blog/forward-deployed-engineer-vs-outsourcing?utm_source=devto&amp;amp;utm_medium=cross-post&amp;amp;utm_campaign=forward-deployed-engineer-vs-outsourcing" rel="noopener noreferrer"&gt;yetmike.com&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>career</category>
      <category>engineering</category>
      <category>consulting</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Podman Lost to Docker. I Stopped Fighting It.</title>
      <dc:creator>Mykhailo</dc:creator>
      <pubDate>Mon, 27 Apr 2026 20:18:32 +0000</pubDate>
      <link>https://dev.to/yetmike/podman-lost-to-docker-i-stopped-fighting-it-21hi</link>
      <guid>https://dev.to/yetmike/podman-lost-to-docker-i-stopped-fighting-it-21hi</guid>
      <description>&lt;p&gt;Most "Podman vs Docker" articles treat it as a technical comparison. It isn't. It's a migration cost problem.&lt;/p&gt;

&lt;p&gt;The technical case for Podman is real: rootless by default (not opt-in like &lt;a href="https://docs.docker.com/engine/security/rootless/" rel="noopener noreferrer"&gt;Docker's 20.10 mode&lt;/a&gt;), no &lt;code&gt;dockerd&lt;/code&gt; running as root, no &lt;a href="https://www.docker.com/pricing/" rel="noopener noreferrer"&gt;$9–15/user/month&lt;/a&gt; for Docker Desktop, and &lt;a href="https://www.redhat.com/en/blog/quadlet-podman" rel="noopener noreferrer"&gt;Quadlet&lt;/a&gt; (5.0, 2025) for native &lt;a href="https://systemd.io/" rel="noopener noreferrer"&gt;systemd&lt;/a&gt; integration. These are genuine architectural wins.&lt;/p&gt;

&lt;p&gt;But &lt;a href="https://survey.stackoverflow.co/2025/technology" rel="noopener noreferrer"&gt;Stack Overflow's 2025 survey&lt;/a&gt; shows Docker at 71.1% adoption — the largest single-year jump of any technology. Podman at 11.1%. &lt;a href="https://www.docker.com/blog/docker-stack-overflow-survey-thank-you-2024/" rel="noopener noreferrer"&gt;Docker Hub&lt;/a&gt;: 318 billion pulls. &lt;a href="https://podman-desktop.io/blog/podman-desktop-2025-journey" rel="noopener noreferrer"&gt;Podman Desktop&lt;/a&gt;: 3 million total downloads since launch.&lt;/p&gt;

&lt;p&gt;That's not a competitor. That's a niche.&lt;/p&gt;

&lt;h2&gt;
  
  
  The question that actually matters
&lt;/h2&gt;

&lt;p&gt;Not "which is better?" but "what context are you in?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Starting fresh — use Podman if it fits.&lt;/strong&gt; On &lt;a href="https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux" rel="noopener noreferrer"&gt;RHEL&lt;/a&gt;, it's the obvious choice: &lt;a href="https://developers.redhat.com/articles/2023/08/03/podman-next-generation-container-management-tool" rel="noopener noreferrer"&gt;Red Hat ships it by default&lt;/a&gt;, Quadlet integrates directly with systemd, rootless-by-default matters when someone audits your runtime. &lt;a href="https://www.cncf.io/projects/podman/" rel="noopener noreferrer"&gt;The CNCF accepted it into sandbox in January 2025&lt;/a&gt;. Greenfield project, no legacy tooling — go for it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Migrating an existing Docker setup — think twice.&lt;/strong&gt; This is where the calculation breaks down. The spreadsheet shows Docker Desktop at $9–15/user/month. It doesn't show:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Migration day&lt;/li&gt;
&lt;li&gt;Debugging socket path differences (&lt;a href="https://podman.io/docs/installation" rel="noopener noreferrer"&gt;Podman uses a different socket location&lt;/a&gt; than Docker)&lt;/li&gt;
&lt;li&gt;Updating CI pipelines built around Docker socket compatibility&lt;/li&gt;
&lt;li&gt;Fixing &lt;a href="https://containers.dev/" rel="noopener noreferrer"&gt;Dev Containers&lt;/a&gt; when VS Code stops finding the right runtime&lt;/li&gt;
&lt;li&gt;The 30-minute Podman explanation for every new hire who's never heard of it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are real hours from real people. None of them ship anything a user will ever see.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Docker won anyway
&lt;/h2&gt;

&lt;p&gt;Not on merit. On surface area.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/features/actions" rel="noopener noreferrer"&gt;GitHub Actions&lt;/a&gt; assumes Docker. &lt;a href="https://rancherdesktop.io/" rel="noopener noreferrer"&gt;Rancher Desktop&lt;/a&gt; defaults to Docker. &lt;a href="https://modelcontextprotocol.io/" rel="noopener noreferrer"&gt;MCP server configs&lt;/a&gt; reference Docker. Every Stack Overflow answer assumes Docker. Every internal platform template your company has written assumes Docker.&lt;/p&gt;

&lt;p&gt;When you switch, you're not just swapping a binary. You're swimming against the accumulated inertia of every tool your team uses daily. Podman's remaining real advantages — daemonless architecture, rootless-by-default, Quadlet — are genuinely better. They're also genuinely invisible to 90% of the people making the decision.&lt;/p&gt;

&lt;p&gt;I wrote about the full trade-off breakdown, including where each argument actually landed and what Docker did and didn't fix, &lt;a href="https://yetmike.com/blog/podman-lost-to-docker/?utm_source=devto&amp;amp;utm_medium=cross-post&amp;amp;utm_campaign=podman-lost-to-docker" rel="noopener noreferrer"&gt;in the original post on yetmike.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The short version: run the numbers with migration costs included. Then decide.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://yetmike.com/blog/podman-lost-to-docker/?utm_source=devto&amp;amp;utm_medium=cross-post&amp;amp;utm_campaign=podman-lost-to-docker" rel="noopener noreferrer"&gt;yetmike.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>podman</category>
      <category>devops</category>
      <category>containers</category>
    </item>
  </channel>
</rss>
