CodeCrafters - Latest topics https://forum.codecrafters.io/latest Latest topics Fri, 24 Apr 2026 05:00:54 +0000 Odin dev-2026-04 is now available! Announcements Hey everyone!

The default Odin version has been updated across all supported challenges.

Previously running on dev-2025-07, we’ve now upgraded to dev-2026-04.

To use the latest version, be sure to update the buildpack version in your repo as well.

1 post - 1 participant

Read full topic

]]>
https://forum.codecrafters.io/t/odin-dev-2026-04-is-now-available/16066 Fri, 24 Apr 2026 05:00:54 +0000 No No No forum.codecrafters.io-topic-16066 Odin dev-2026-04 is now available!
New Feature: Custom commit messages Announcements Hey everyone!

We now support custom commit messages in the CLI, thanks to @0xhasann!

Previously, codecrafters submit used a hardcoded message. With this update, you can now do:

codecrafters submit -m "describe your changes"

To use this feature, please update your CLI to the latest version.

Give it a try, and let us know how it works for you!

1 post - 1 participant

Read full topic

]]>
https://forum.codecrafters.io/t/new-feature-custom-commit-messages/16062 Thu, 23 Apr 2026 05:27:49 +0000 No No No forum.codecrafters.io-topic-16062 New Feature: Custom commit messages
./your_program.sh: cannot execute: required file not found Challenges I’m stuck on improving my solution.

I’ve tried to run it locally following the README.md file and some other answers in this forum, but i cannot run without problem.

Here are my logs:

➜ ./your_program.sh 
bash: ./your_program.sh: cannot execute: required file not found

Here’s a link to my repo:

gabrielbudke/codecrafters-claude-code-python: Build your own Claude Code

6 posts - 2 participants

Read full topic

]]>
https://forum.codecrafters.io/t/your-program-sh-cannot-execute-required-file-not-found/16059 Wed, 22 Apr 2026 03:35:57 +0000 No No No forum.codecrafters.io-topic-16059 ./your_program.sh: cannot execute: required file not found
Ruby 4.0 is now available! Announcements Hey everyone!

The default Ruby version has been updated across all supported challenges.

Previously running on v3.4, we’ve now upgraded to v4.0.

To use the latest version, be sure to update the buildpack version in your repo as well.

1 post - 1 participant

Read full topic

]]>
https://forum.codecrafters.io/t/ruby-4-0-is-now-available/16058 Mon, 20 Apr 2026 06:32:02 +0000 No No No forum.codecrafters.io-topic-16058 Ruby 4.0 is now available!
Rust 1.95 is now available! Announcements Hey everyone!

The default Rust version has been updated across all supported challenges.

Previously running on v1.94, we’ve now upgraded to v1.95.

To use the latest version, be sure to update the buildpack version in your repo as well.

1 post - 1 participant

Read full topic

]]>
https://forum.codecrafters.io/t/rust-1-95-is-now-available/16057 Mon, 20 Apr 2026 05:22:59 +0000 No No No forum.codecrafters.io-topic-16057 Rust 1.95 is now available!
Spotted a copy-paste typo in the dns-server-tester go.mod Bug Reports Hey team,

I was reading the source code for the DNS tester and noticed a naming collision.

It looks like a bit of copy-paste debt from the grep challenge, the go.mod for the DNS tester is currently identifying itself as the grep-tester dns-server-tester/go.mod at e491a49873be71b5810e0e67525d16d6b3e1a5e1 · codecrafters-io/dns-server-tester · GitHub

This also flows into the internal imports and the Makefile.

I’ve raised a PR to tidy this up so it correctly identifies as dns-server-tester, which should help avoid naming collisions .

PR Link: chore: fix incorrect module naming and internal paths by dhotrey · Pull Request #36 · codecrafters-io/dns-server-tester · GitHub

Also, I noticed that in the Makefiles for most of the testers, the copy_course_file directive points to /repo/build-your-own-<x>/contents/course-definition.yml, but in practice, in most repos, it has been moved to the root: /repo/build-your-own-<x>/course-definition.yml.

example from http-server-tester :

copy_course_file:
	hub api \
		repos/codecrafters-io/build-your-own-http-server/contents/course-definition.yml \
		| jq -r .content \
		| base64 -d \
		> internal/test_helpers/course_definition.yml

If you guys give me the go-ahead, I don’t mind fixing and raising a PR for this pattern across the other testers as well!

2 posts - 2 participants

Read full topic

]]>
https://forum.codecrafters.io/t/spotted-a-copy-paste-typo-in-the-dns-server-tester-go-mod/16056 Sun, 19 Apr 2026 22:28:57 +0000 No No No forum.codecrafters.io-topic-16056 Spotted a copy-paste typo in the dns-server-tester go.mod
How to debug weird expected response? Challenges I’m stuck on Stage #FY6

I’ve tried running the same commands from multiple clients connected locally, and everything is fine

Here are my logs:

[tester::#FY6] [client-1] ✔︎ Received ["OK", 23, 1, "1"]
[tester::#FY6] [client-2] $ redis-cli GET banana
[tester::#FY6] [client-2] Sent bytes: "*2\r\n$3\r\nGET\r\n$6\r\nbanana\r\n"
[tester::#FY6] [client-2] Received bytes: "$-1\r\n"
[tester::#FY6] [client-2] Received RESP null bulk string: "$-1\r\n"
[tester::#FY6] Expected bulk string, found null bulk string ($-1\r\n)
[tester::#FY6] Test failed
[tester::#FY6] Terminating program
[your_program] key: banana | client_data:  {}
[your_program] DEBUGGG !!!! 
[tester::#FY6] Program terminated successfully

And here’s a snippet of my code:

3 posts - 2 participants

Read full topic

]]>
https://forum.codecrafters.io/t/how-to-debug-weird-expected-response/16055 Sat, 18 Apr 2026 23:26:42 +0000 No No No forum.codecrafters.io-topic-16055 How to debug weird expected response?
Testcase failed: BLPOP on string value Challenges How should we handle it if a BLPOP operation is called on a key which stored a string value previously?
The testcases are as follows:
SET mango banana
BLPOP mango 0.3
Are we to assume the BLPOP operation changes the type of the value stored at key mango, to a list instead?

2 posts - 2 participants

Read full topic

]]>
https://forum.codecrafters.io/t/testcase-failed-blpop-on-string-value/16054 Sat, 18 Apr 2026 05:22:07 +0000 No No No forum.codecrafters.io-topic-16054 Testcase failed: BLPOP on string value
New extension: AOF Persistence (Redis) Announcements Hey everyone!

The next extension for the Redis challenge is now live: AOF Persistence.

AOF (Append-Only File) Persistence lets your Redis server persist data to disk by logging every write operation. This means your data can be reconstructed by replaying the log, even after a restart.

By the end of this extension, your Redis implementation will support:

  • Reading and applying AOF configuration
  • Creating AOF directory and files
  • Writing commands to the AOF log (single and multiple commands)
  • Replaying the AOF log on startup (single and multiple commands) to restore state

Here’s the stage breakdown:

Please give this a try and let us know how it can be improved! @UdeshyaDhungana (author of this extension) and I will be available here to help out with any tester or instruction-related issues.

1 post - 1 participant

Read full topic

]]>
https://forum.codecrafters.io/t/new-extension-aof-persistence-redis/16029 Fri, 17 Apr 2026 17:56:57 +0000 No No No forum.codecrafters.io-topic-16029 New extension: AOF Persistence (Redis)
OCaml track now supports Git Announcements Hey everyone!

The OCaml track now includes the Build your own Git challenge.

Ready to put your OCaml skills to the test? Jump into the OCaml track, and let us know how it goes!

1 post - 1 participant

Read full topic

]]>
https://forum.codecrafters.io/t/ocaml-track-now-supports-git/16052 Thu, 16 Apr 2026 19:54:43 +0000 No No No forum.codecrafters.io-topic-16052 OCaml track now supports Git
`codecrafters submit` error Bug Reports CodeCrafters/BuildYourBitTorrent/codecrafters-bittorrent-rust$ codecrafters submit
Submitting changes (commit: bb9abfc)…

push changes: run git command: fatal: unable to access ‘https://git.codecrafters.io/769d7af23164b99c/’: gnutls_handshake() failed: The TLS connection was non-properly terminated.
. Error: exit status 128

3 posts - 3 participants

Read full topic

]]>
https://forum.codecrafters.io/t/codecrafters-submit-error/16051 Wed, 15 Apr 2026 11:02:12 +0000 No Yes No forum.codecrafters.io-topic-16051 `codecrafters submit` error
Codecrafters - Issue while setting up with Python. ping command not found General

trying this command listed in setup.

``curl -fsSL ``https://codecrafters.io/install.sh`` | bashcodecrafters ping``

Still not working.

4 posts - 3 participants

Read full topic

]]>
https://forum.codecrafters.io/t/codecrafters-issue-while-setting-up-with-python-ping-command-not-found/16050 Wed, 15 Apr 2026 10:34:14 +0000 No Yes No forum.codecrafters.io-topic-16050 Codecrafters - Issue while setting up with Python. ping command not found
Kotlin 2.3 is now available Announcements Hey everyone!

The default Kotlin version has been updated across all supported challenges!

Previously running on v2.2, we’ve now upgraded to v2.3.

To use the latest version, be sure to update the buildpack version in your repo as well.

1 post - 1 participant

Read full topic

]]>
https://forum.codecrafters.io/t/kotlin-2-3-is-now-available/16047 Mon, 13 Apr 2026 00:29:23 +0000 No No No forum.codecrafters.io-topic-16047 Kotlin 2.3 is now available
#pg8 (Functions without arguments): Add check for redefining clock()? Feature Requests I was wondering about the correct behavior for code like:

print clock();
fun clock() {
  return 0;
}
print clock();

I think that we need to allow clock to be shadowed by the new definition. This means that the root program environment needs to be populated with our builtins, rather than using a separate lookup table (which would prevent shadowing). I had made this mistake previously, however there doesn’t seem to be a test for it.

There might also be a test to see whether the “evaluate” function from before can also handle builtins, not just “run”.

4 posts - 2 participants

Read full topic

]]>
https://forum.codecrafters.io/t/pg8-functions-without-arguments-add-check-for-redefining-clock/16044 Sat, 11 Apr 2026 03:13:22 +0000 No No No forum.codecrafters.io-topic-16044 #pg8 (Functions without arguments): Add check for redefining clock()?
New extension: Optimistic Locking (Redis) Announcements Hey everyone!

The next extension for the Redis challenge is now live: Optimistic Locking.

Optimistic Locking lets your Redis server handle concurrent updates safely by ensuring a transaction only succeeds if the data hasn’t changed after being watched.

By the end of this extension, your Redis implementation will support:

  • Monitoring keys for changes using WATCH
  • Aborting transactions if watched keys change before EXEC
  • Watching multiple keys at once
  • Handling missing keys correctly
  • Clearing watches with UNWATCH
  • Automatically unwatching on EXEC and DISCARD

Here’s the stage breakdown:

Please give this a try and let us know how it can be improved! @UdeshyaDhungana (author of this extension) and I will be available here to help out with any tester or instruction-related issues.

1 post - 1 participant

Read full topic

]]>
https://forum.codecrafters.io/t/new-extension-optimistic-locking-redis/16015 Wed, 08 Apr 2026 10:57:04 +0000 No No No forum.codecrafters.io-topic-16015 New extension: Optimistic Locking (Redis)
GEOSEARCH difficulty feels underrated Feature Requests I think the GEOSEARCH stage being labeled Easy is a bit misleading.

If the intended solution is to decode every point in the zset and brute-force the distance check against the query center, then yes, the stage is fairly straightforward. But if the goal is to understand or approximate how Redis actually makes geo queries efficient by leveraging geocells and sorted sets, this stage is much more subtle than “easy” suggests.

I’d suggest either:

  • keeping the stage as Easy, but explicitly saying that a brute-force implementation is acceptable and expected for this stage, or
  • bumping the difficulty to at least Medium (preferably Hard) if the stage is meant to push people toward a more Redis-like spatial indexing approach. It is probably also helpful to give some hints to push people in the right direction, otherwise it might not be immediately clear how the encoding and backing data store (sorted sets) actually helps with GEOSEARCH.

FWIW that was possibly the most difficult task I’ve ever done on this platform, required lots of research and meticulous implementation. Though I must say that it was also incredibly instructive and enjoyable :slight_smile:

1 post - 1 participant

Read full topic

]]>
https://forum.codecrafters.io/t/geosearch-difficulty-feels-underrated/16035 Tue, 07 Apr 2026 03:44:42 +0000 No No No forum.codecrafters.io-topic-16035 GEOSEARCH difficulty feels underrated
New in Scala track: BitTorrent challenge + v3.8 Support Announcements Hey everyone!

The Scala track now includes the Build your own BitTorrent challenge.

We’ve also upgraded Scala to version 3.8 across all supported challenges.

Ready to put your Scala skills to the test? Jump into the Scala track, and let us know how it goes!

1 post - 1 participant

Read full topic

]]>
https://forum.codecrafters.io/t/new-in-scala-track-bittorrent-challenge-v3-8-support/16034 Mon, 06 Apr 2026 22:38:37 +0000 No No No forum.codecrafters.io-topic-16034 New in Scala track: BitTorrent challenge + v3.8 Support
Weird behavior in C Challenges


I’m doing this project in C. Every time I push my work, it fails with a couple of characters at the end of output. This always happens when testing puts some output into a file with echo command and uses cat command to print the output. On local, it almost never happens. When it does, it is so rare that it is almost impossible to debug.
I am following a pretty standard approach of redirecting standard output to a specified file name and use execvp to execute external binary. I debugged and checked that my string is right, null-terminating character is in right place, pointers are pointing to the correct location, my implementation of echo is correct, etc. Nothing works.

Has anybody come across this issue?

Here is the link to my repo regarding this issue: codecrafters-shell-c/src/execute_bin.c at main · MaxJuneKim/codecrafters-shell-c · GitHub

6 posts - 3 participants

Read full topic

]]>
https://forum.codecrafters.io/t/weird-behavior-in-c/16033 Mon, 06 Apr 2026 22:26:05 +0000 No Yes No forum.codecrafters.io-topic-16033 Weird behavior in C
Unable to submit solutions Challenges When attempting to submit my solution, I am greeted by the following error:

___@arch in ~/codecrafters-http-server-elixir
$ codecrafters submit
commit changes: create commit: error: Couldn’t get agent socket?

fatal: failed to write commit object
. Error: exit status 128

The only alteration made to the provided code so far has been the uncommenting of the required lines.

6 posts - 3 participants

Read full topic

]]>
https://forum.codecrafters.io/t/unable-to-submit-solutions/16032 Mon, 06 Apr 2026 22:03:04 +0000 No Yes No forum.codecrafters.io-topic-16032 Unable to submit solutions
To what extent is using the standard library considered cheating? General I’ve been taking the http challenge a few times in different languages like Go and Python. I’ve been enjoying myself so far, but I always have a voice in the back of my head asking if the way I implement things is the way it’s “intended” to be. To an extent the way I have been approaching every challenge has been something like “the standard library is free game, other dependencies (except for things like linters) aren’t.” But even this feels a bit… sketchy? An obvious example being the grep challenge, where using in built regex is probably considered cheating, right? Which gets me back to the http challenge. Different languages have different level of support for “common” tasks, the Go stdlib is famously robust, while node tends to be a bit more barebones.

Ultimately I am just getting at the question in the title, is the idea to basically only use “bare” syntax to do things like string parsing? Concurrency? Python’s stblib has the urllib package which would handle the target field of the request line trivially, go would probably able to build a production ready http server using only the stdlib pretty easily compared to most of the other languages available. Up to this point my answer has been a sort of “I am here to learn, so if it is too easy then it’s not allowed” but like I said, there is a voice in my head that is saying things like “an important skill to learn as a developer is delegation to other dependencies when needed”, cryptography being the go to example.

4 posts - 3 participants

Read full topic

]]>
https://forum.codecrafters.io/t/to-what-extent-is-using-the-standard-library-considered-cheating/16031 Mon, 06 Apr 2026 15:24:47 +0000 No No No forum.codecrafters.io-topic-16031 To what extent is using the standard library considered cheating?
Bug in Starting background jobs #at7? Bug Reports I’m stuck on Stage #AT7 and I think there’s a bug in the testing code.

The process is running in background, I can look up the pid in ps.

My shell:

$ sleep 15000 &
[1] 90531

Bash:

$ ps aux | grep 90531
dom 90531 0.0 0.0 5572 2140 pts/3 S+ 21:57 0:00 sleep 15000
dom 90536 0.0 0.0 6520 2388 pts/0 S+ 21:57 0:00 grep --color=always 90531

It is correctly running in background. Yet, the test fails here:

[tester::#AT7] Running tests for Stage #AT7 (Background Jobs - Starting background jobs)
[tester::#AT7] Running ./your_program.sh
[your-program] $ sleep 500 &
[your-program] [1] 44
[tester::#AT7] Could not find process with PID 44
[tester::#AT7] Test failed

I think the 500 ms sleep may be too short and my machine too slow, so the process terminates before the test has had a chance to verify it’s running. Just a guess.

12 posts - 4 participants

Read full topic

]]>
https://forum.codecrafters.io/t/bug-in-starting-background-jobs-at7/16026 Sun, 05 Apr 2026 20:01:54 +0000 No Yes No forum.codecrafters.io-topic-16026 Bug in Starting background jobs #at7?
Stuck with #SX3 Challenges I’m stuck on Stage #SX3

Im not sure why but but in local my implementation works but test fails.

\[tester::#SX3\] Running tests for Stage #SX3 (History Persistence - Append history to file)
\[tester::#SX3\] Original history file content:
\[tester::#SX3\] \[/tmp/pear.txt\] echo grape strawberry orange
\[tester::#SX3\] \[/tmp/pear.txt\] echo pineapple apple
\[tester::#SX3\] \[/tmp/pear.txt\]
\[tester::#SX3\] Running ./your_program.sh
\[your-program\] $ echo strawberry blueberry pear
\[your-program\] strawberry blueberry pear
\[tester::#SX3\] ✓ Ran echo strawberry blueberry pear
\[your-program\] $ echo apple pear strawberry
\[your-program\] apple pear strawberry
\[tester::#SX3\] ✓ Ran echo apple pear strawberry
\[your-program\] $ echo strawberry grape pineapple
\[your-program\] strawberry grape pineapple
\[tester::#SX3\] ✓ Ran echo strawberry grape pineapple
\[your-program\] $ history -a /tmp/pear.txt
\[tester::#SX3\] Reading contents from /tmp/pear.txt
\[tester::#SX3\] \[/tmp/pear.txt\] echo grape strawberry orange
\[tester::#SX3\] \[/tmp/pear.txt\] echo pineapple apple
\[tester::#SX3\] \[/tmp/pear.txt\]
\[tester::#SX3\] \[/tmp/pear.txt\]
\[tester::#SX3\] ✓ Found command “echo grape strawberry orange” in /tmp/pear.txt
\[tester::#SX3\] ✓ Found command “echo pineapple apple” in /tmp/pear.txt
\[tester::#SX3\] expected command “echo strawberry blueberry pear” at line 3, got “”
\[tester::#SX3\] Test failed
package main

import (
	"fmt"
	"io"
	"os"
	"os/exec"
	"slices"
	"strconv"
	"strings"
	"sync"

	"github.com/chzyer/readline"
	"github.com/codecrafters-io/shell-starter-go/app/bellcompleter"
)

var _ = fmt.Print

var buildInCommands = []string{"echo", "exit", "type", "pwd", "history"}
var dividerCommands = []string{">", "1>", "2>", ">>", "1>>", "2>>"}
var history string = ".shell_history/" + strconv.Itoa(os.Getpid())
var historyAppendOffset int = 0

func main() {
	if os.Getenv("HISTFILE") != "" {
		history = os.Getenv("HISTFILE")
	} else {
		f, e := os.Create(history)
		if e != nil {
			panic(e)
		}
		defer f.Close()
	}
	prefixCompleter := readline.NewPrefixCompleter(
		readline.PcItem("echo"),
		readline.PcItem("exit"),
	)
	completer := &bellcompleter.BellCompleter{Completer: prefixCompleter, TabCount: 0}
	cfg := &readline.Config{
		Prompt:                 "$ ",
		AutoComplete:           completer,
		InterruptPrompt:        "^C",
		EOFPrompt:              "exit",
		HistoryFile:            history,
		DisableAutoSaveHistory: false,
	}

	// Initialize the readline instance.
	rl, err := readline.NewEx(cfg)
	if err != nil {
		panic(err)
	}
	defer rl.Close() // Ensure the terminal is restored to its original state on exit

	for {

		if err != nil {
			panic("input failed")
		}
		line, err := rl.Readline()
		tokens := parseCommand(line)
		commands := make([][]string, 1)
		i := 0
		for _, token := range tokens {
			if token == "|" {
				// fmt.Println("Ci")
				commands = append(commands, []string{})
				i++
			} else {
				commands[i] = append(commands[i], token)
			}

		}
		if err != nil {
			panic("Failed!")
		}
		var wg sync.WaitGroup
		pipeReaders := make([]*io.PipeReader, len(commands))
		pipeWriters := make([]*io.PipeWriter, len(commands))
		for i := 0; i < len(commands)-1; i++ {
			pipeReaders[i+1], pipeWriters[i] = io.Pipe()
		}
		for i, command := range commands {
			if command[0] == "exit" {
				os.Exit(0)
			}
			wg.Add(1)
			go func(cmd []string, idx int) {
				if pipeReaders[idx] != nil {
					defer pipeReaders[idx].Close()
				}
				if pipeWriters[idx] != nil {
					defer pipeWriters[idx].Close()
				}
				executeCommand(cmd, pipeWriters[idx], pipeReaders[idx], rl)
				defer wg.Done()

			}(command, i)
		}
		wg.Wait()

	}
}

func executeCommand(command []string, pipeWriter *io.PipeWriter, pipeReader *io.PipeReader, rl *readline.Instance) {
	execTokens, outStd, redirectionType, _ := extractPipelineCommands(command)

	stdin, stdout, stderr := getIOs(pipeReader, pipeWriter, redirectionType, outStd)

	var commandError error
	if command[0] == "echo" {
		fmt.Fprintln(stdout, strings.Join(execTokens[1:], " "))
	} else if command[0] == "type" {
		fmt.Fprintln(stdout, handleTypeCommand(command))
	} else if command[0] == "pwd" {
		currentPath, _ := os.Getwd()
		fmt.Fprintln(stdout, currentPath)
	} else if command[0] == "cd" {
		pathToGo := command[1]
		if command[1] == "~" {
			pathToGo = os.Getenv("HOME")
		}
		if err := os.Chdir(pathToGo); err != nil {
			fmt.Fprintf(stderr, "cd: %s: No such file or directory\n", pathToGo)
		}
	} else if command[0] == "history" {
		if len(execTokens) > 1 {

			switch execTokens[1] {
			case "-r":
				appenedFileIntoHistory(execTokens[2], rl)
				return
			case "-w":
				appendHistoryIntoFile(execTokens[2])
			case "-a":
				createNewHistory(execTokens[2])
			}
		}
		f, _ := os.ReadFile(history)
		lines := strings.Split(strings.TrimRight(string(f), "\n"), "\n")

		linesToPrint := len(lines)
		if len(execTokens) > 1 {
			i, _ := strconv.Atoi(execTokens[1])
			linesToPrint = min(linesToPrint, i)
			// fmt.Println(linesToPrint)
		}
		for i, l := range lines[(len(lines) - linesToPrint):] {
			if l != "" {
				fmt.Fprintf(stdout, "  %d  %s\n", (i + (len(lines) - linesToPrint) + 1), l)
			}
		}
	} else {
		commandError = executeSingleCommand(execTokens, stdin, stdout, stderr)

	}
	errorOutput := parseError(commandError)
	switch redirectionType {
	case "redirect", "redirectAppend":
		if errorOutput != "" {
			fmt.Println(errorOutput)
		}
	case "redirectError", "redirectAppendError":
		if stdout != nil {

		}
	}
}

func appenedFileIntoHistory(input string, rl *readline.Instance) {
	historyFile, _ := os.ReadFile(input)
	lines := strings.Split(strings.TrimRight(string(historyFile), "\n"), "\n")
	for _, line := range lines {
		rl.SaveHistory(line)
	}
}

func appendHistoryIntoFile(output string) {
	file, _ := os.Create(output)
	historyData, _ := os.ReadFile(history)
	file.Write(historyData)
}

func createNewHistory(output string) {
	historyData, e := os.ReadFile(history)
	if e != nil {
		panic(e)
	}
	lines := strings.Split(strings.TrimRight(string(historyData), "\n"), "\n")

	existingFileLines, _ := os.ReadFile(output)
	newLines := strings.Split(strings.Trim(string(existingFileLines), "\n"), "\n")
	newLines = append(newLines, lines[historyAppendOffset:]...)
	historyAppendOffset = len(lines)
	file, e := os.OpenFile(output, os.O_CREATE|os.O_WRONLY, 0644)
	if e != nil {
		panic(e)
	}
	defer file.Close()
	for _, line := range newLines {
		file.WriteString(line + "\n")
	}
}

func statOrZero(f *os.File) int64 {
	if fi, err := f.Stat(); err == nil {
		return fi.Size()
	}
	return 0
}

func getIOs(pipeReader *io.PipeReader, pipeWriter *io.PipeWriter, redirectionType string, outStd string) (io.Reader, io.Writer, io.Writer) {
	var stdin io.Reader
	if pipeReader != nil {
		stdin = pipeReader
	}
	var stdout io.Writer
	var stderr io.Writer
	stdout = os.Stdout
	stderr = os.Stderr
	if pipeWriter != nil {
		stdout = pipeWriter
	} else {
		switch redirectionType {
		case "redirect":
			f, _ := os.OpenFile(outStd, os.O_CREATE|os.O_WRONLY, 0644)
			stdout = f
		case "redirectAppend":
			f, _ := os.OpenFile(outStd, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
			stdout = f
		case "redirectError":
			f, _ := os.OpenFile(outStd, os.O_CREATE|os.O_WRONLY, 0644)
			stderr = f
		case "redirectAppendError":
			f, _ := os.OpenFile(outStd, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
			stderr = f
		}
	}
	return stdin, stdout, stderr

}

func executeSingleCommand(command []string, pipeReader io.Reader, pipeWriter io.Writer, pipeErr io.Writer) error {

	path := checkAndGetInPaths(command[0], strings.Split(os.Getenv("PATH"), ":"))
	if path == "" {
		fmt.Fprintln(os.Stderr, command[0]+": not found")
		return nil
	} else {
		var cmd *exec.Cmd
		if len(command) == 1 {
			cmd = exec.Command(command[0])
		} else {
			cmd = exec.Command(command[0], command[1:]...)
		}
		cmd.Stdin = pipeReader
		cmd.Stdout = pipeWriter
		cmd.Stderr = pipeErr
		return cmd.Run()
	}

}

func handleTypeCommand(command []string) string {
	if slices.Contains(buildInCommands, command[1]) {
		return command[1] + " is a shell builtin"
	} else {
		path := checkAndGetInPaths(command[1], strings.Split(os.Getenv("PATH"), ":"))
		if path == "" {
			return command[1] + ": not found"
		} else {
			return command[1] + " is " + path
		}
	}
}

func checkAndGetInPaths(command string, paths []string) string {
	for _, path := range paths {
		foundPath, err := exec.LookPath(path + "/" + command)
		if err == nil {
			return foundPath
		}
	}
	return ""
}

func parseCommand(line string) []string {

	var res []string
	var currentWord strings.Builder
	isSingleQuotes := false
	isDoubleQuotes := false
	isEscapeMode := false
	for _, ch := range strings.Trim(line, "\n") {
		// fmt.P/rintln(res)
		switch {
		case isEscapeMode:
			isEscapeMode = false
			currentWord.WriteRune(ch)
		case ch == '\\' && !isSingleQuotes:
			isEscapeMode = true
		case ch == '\'' && !isDoubleQuotes:
			isSingleQuotes = !isSingleQuotes

		case ch == '"' && !isSingleQuotes:
			isDoubleQuotes = !isDoubleQuotes
		case ch == ' ' && !isSingleQuotes && !isDoubleQuotes:
			if currentWord.Len() > 0 {
				res = append(res, currentWord.String())
				currentWord.Reset()
			}
		default:
			currentWord.WriteRune(ch)
		}
	}
	if currentWord.Len() > 0 {
		res = append(res, currentWord.String())
	}
	// fmt.Println(res)
	return res
}

func extractPipelineCommands(tokens []string) ([]string, string, string, bool) {
	for i, t := range tokens {
		if !slices.Contains(dividerCommands, t) {
			continue
		}
		if i+1 >= len(tokens) {
			return nil, "", "redirect", false
		}
		var commandType string
		switch {
		case t == ">" || t == "1>":
			commandType = "redirect"
		case t == "2>":
			commandType = "redirectError"

		case t == ">>" || t == "1>>":
			commandType = "redirectAppend"

		case t == "2>>":
			commandType = "redirectAppendError"
		}
		return tokens[:i], strings.Join(tokens[i+1:], " "), commandType, true

	}
	return tokens, "", "none", true
}

func parseError(err error) string {
	if err == nil {
		return ""
	}
	if exitErr, ok := err.(*exec.ExitError); ok {
		return strings.Trim(string(exitErr.Stderr), "\n")
	}
	return fmt.Sprintf("%v", err)
}

Please ignore the terrible code, im kind of new to golang

6 posts - 3 participants

Read full topic

]]>
https://forum.codecrafters.io/t/stuck-with-sx3/16025 Sun, 05 Apr 2026 12:05:49 +0000 No Yes No forum.codecrafters.io-topic-16025 Stuck with #SX3
Codecrafters ping command fails in codecrafters repo Challenges

i haven’t touch this repo for 9 months

i tried cloning the repo and then doing codecrafters ping the command still failed

this is my github repo GitHub - wigiwee/codecrafters-redis-java · GitHub

3 posts - 2 participants

Read full topic

]]>
https://forum.codecrafters.io/t/codecrafters-ping-command-fails-in-codecrafters-repo/16024 Sun, 05 Apr 2026 07:43:13 +0000 No Yes No forum.codecrafters.io-topic-16024 Codecrafters ping command fails in codecrafters repo
Request to make "Build your own shell" available for this month as well General Hi, I have started this challenge last month (completed 9 stages) and suddenly today I see it is not free anymore. Can you please make it available for this month as well? I discovered about the platform last month only.

Please make it available :slight_smile:

4 posts - 3 participants

Read full topic

]]>
https://forum.codecrafters.io/t/request-to-make-build-your-own-shell-available-for-this-month-as-well/16022 Thu, 02 Apr 2026 17:35:08 +0000 No No No forum.codecrafters.io-topic-16022 Request to make "Build your own shell" available for this month as well
Rust 1.94 is now available! Announcements Hey everyone!

The default Rust version has been updated across all supported challenges!

Previously running on v1.93, we’ve now upgraded to v1.94.

To use the latest version, be sure to update the buildpack version in your repo as well.

1 post - 1 participant

Read full topic

]]>
https://forum.codecrafters.io/t/rust-1-94-is-now-available/16020 Wed, 01 Apr 2026 19:59:42 +0000 No No No forum.codecrafters.io-topic-16020 Rust 1.94 is now available!
April 2026 Roadmap Announcements Hey everyone!

Here’s what’s upcoming for April 2026:

“Optimistic Locking” extension for Build your own Redis

“AOF Persistence” extension for Build your own Redis

Language support:

  • Scala support for Build your own BitTorrent
  • OCaml support for Build your own Git
  • PHP support for Build your own DNS server

We try our best to stick to user votes, so if you’d like to influence what we build in the upcoming months, please vote / suggest ideas here!

1 post - 1 participant

Read full topic

]]>
https://forum.codecrafters.io/t/april-2026-roadmap/16016 Wed, 01 Apr 2026 17:04:01 +0000 No No No forum.codecrafters.io-topic-16016 April 2026 Roadmap
New extension: Background Jobs (Shell) Announcements Hey everyone!

The next extension for the Shell challenge is now live: Background Jobs.

Background jobs allow your shell to run commands without blocking the shell, so you can keep working while tasks run in the background.

Once you complete this extension, your shell will support behaviors like:

make build &
echo "Working on something else while build runs..."
jobs

Here’s the stage breakdown:

Please give this a try and let us know how it can be improved! @UdeshyaDhungana (author of this extension) and I will be available here to help out with any tester or instruction-related issues.

1 post - 1 participant

Read full topic

]]>
https://forum.codecrafters.io/t/new-extension-background-jobs-shell/15957 Wed, 01 Apr 2026 05:33:16 +0000 No No No forum.codecrafters.io-topic-15957 New extension: Background Jobs (Shell)
Implement multiple pipeline with builtin Challenges I’m stuck on Stage #NY9

I’ve tried to implement this features using multiprocessing and pipe.when i run my executable (./shell) it gives right output but tester fails.

Here are my logs:

[tester::#NY9] ^ Line does not match expected value.
[tester::#NY9] Expected: "       1       1      16"
[tester::#NY9] Received: "$ " (trailing space)

And here’s a snippet of my code:

 int fd[2];

        int prev_pipe_read_end = 0;
        std::vector<pid_t> child_pids;

        int original_stdin = dup(STDIN_FILENO);
        int original_stdout = dup(STDOUT_FILENO);
        // Flag to determine if we need to fork built-ins in pipeline
        // Since we have multiple commands, we should fork ALL commands
        //  bool is_pipeline = (cmd_queue.size() > 0);

        /*

             TODO_1: let do this with  first example : pwd | grep "pwd"
             1. parent writes on the pipe write end and store the read end for the next commadn
             2. First step output of pwd is written in write end of the pipe and store  its read  end for the next command
             3. Then for a grep which is not a builtin command.
             4. It reads fron the read end of the previoss pipe, execute accroding them -> ouput is written current pipe write end and store the read end in parent processs for next commaand

        */

        while (!cmd_queue.empty())
        {
            auto current_cmd = cmd_queue.front();
            cmd_queue.pop();
            bool is_last = cmd_queue.empty();

            if (!is_last)
            {
                if (pipe(fd) == -1)
                {
                    perror("pipe");
                    exit(1);
                }
            }

           
              // For pipelines, we fork for ALL commands (including built-ins)
            // This is simpler and more reliable
            pid_t pid = fork();
        
            if(pid == 0) {
                // Setup input from previous pipe
                if (prev_pipe_read_end != 0)
                {
                    dup2(prev_pipe_read_end, STDIN_FILENO);
                    close(prev_pipe_read_end);
                }

              
                 // Setup output to next pipe (if not last)
                if (!is_last)
                {
                    close(fd[0]);  // Close read end in child
                    dup2(fd[1], STDOUT_FILENO);
                    close(fd[1]);  // Close write end after dup2
                }

                // Handle redirections for the pipeline
                // Only apply output redirection to the last command
                if (is_last && ps.has_output_redirect())
                {
                    int out_fd = open(ps.get_output_file().c_str(),
                                     O_WRONLY | O_CREAT | (ps.is_append_mode() ? O_APPEND : O_TRUNC),
                                     0777);
                    if (out_fd != -1)
                    {
                        dup2(out_fd, STDOUT_FILENO);
                        close(out_fd);
                    }
                }

                // Apply error redirection to all commands in pipeline
                if (ps.has_error_redirect())
                {
                    int err_fd = open(ps.get_error_file().c_str(),
                                     O_WRONLY | O_CREAT | (ps.is_append_mode() ? O_APPEND : O_TRUNC),
                                     0777);
                    if (err_fd != -1)
                    {
                        dup2(err_fd, STDERR_FILENO);
                        close(err_fd);
                    }
                }


                 if (current_cmd.is_builtin)
                {
                    auto builtin_cmd = Builtin<Parser>::getMap()[current_cmd.cmd];
                    builtin_cmd->execute(current_cmd.argv);
                    fflush(stdout);
                    fflush(stderr);
                    exit(0);  // Important: Exit child after built-in execution
                }
                else
                {
                    execvp(current_cmd.cmd.c_str(), exec_vector(current_cmd.argv).data());
                    perror("execvp");
                    exit(1);
                }

            } else if(pid > 0) {
                child_pids.push_back(pid);
                
                // Close previous pipe read end in parent
                if (prev_pipe_read_end != 0)
                {
                    close(prev_pipe_read_end);
                }


                  // Setup for next command
                if (!is_last)
                {
                    close(fd[1]);  // Close write end in parent
                    prev_pipe_read_end = fd[0];  // Save read end for next command
                }
                else
                {
                    // Last command - close any remaining pipe read end
                    if (prev_pipe_read_end != 0)
                    {
                        close(prev_pipe_read_end);
                        prev_pipe_read_end = 0;
                    }
                }
            } else {
                perror("fork");
                exit(1);
            }
        

        
        }

        
        

        for (pid_t pid : child_pids)
        {
            int status;
            waitpid(pid, &status, 0);
        }


        // Restore original stdin/stdout
        dup2(original_stdin, STDIN_FILENO);
        dup2(original_stdout, STDOUT_FILENO);
        close(original_stdin);
        close(original_stdout);

9 posts - 3 participants

Read full topic

]]>
https://forum.codecrafters.io/t/implement-multiple-pipeline-with-builtin/16012 Fri, 27 Mar 2026 15:45:33 +0000 No Yes No forum.codecrafters.io-topic-16012 Implement multiple pipeline with builtin
Creating a dumb terminal Challenges I’m stuck on Stage #QP2.

So i did change java version to 17 and add - - enable-native .

i added the - - enable-native on edit config → modify options →add vm options and nothing changed.

i added - - enable-native to pom.xml like this inside compile plug :

–enable-native

and nothing changed , the same error .

it worked when i run java -jar target/.jar , but i want to run it on intellij IDE .

THE ERROR:

Screenshot From 2026-03-26 16-45-29

What could be the solution ?

7 posts - 4 participants

Read full topic

]]>
https://forum.codecrafters.io/t/creating-a-dumb-terminal/16011 Thu, 26 Mar 2026 13:51:45 +0000 No Yes No forum.codecrafters.io-topic-16011 Creating a dumb terminal
Could not locate Gemfile Bug Reports I’m stuck on Stage #ZV2.

I’ve tried to find similar problems on that stage:

Here are my logs from test run:

[compile] Moved ./.codecrafters/run.sh → ./your_program.sh
[compile] Compilation successful.
Debug = true
[tester::#ZV2] Running tests for Stage #ZV2 (Filename Completion - File completion)
[tester::#ZV2] [working_dir] - pineapple-71.txt
[tester::#ZV2] Running ./your_program.sh
[your-program] Could not locate Gemfile
[tester::#ZV2] ^ Expected prompt ("$ ") but received "Could not locate Gemfile"
[tester::#ZV2] Test failed

And here’s a snippet of .codecrafters/run.sh:

#!/bin/sh
#
# This script is used to run your program on CodeCrafters
#
# This runs after .codecrafters/compile.sh
#
# Learn more: https://codecrafters.io/program-interface

set -e # Exit on failure

exec bundle exec ruby app/main.rb "$@"

4 posts - 3 participants

Read full topic

]]>
https://forum.codecrafters.io/t/could-not-locate-gemfile/16007 Sun, 22 Mar 2026 18:20:23 +0000 No Yes No forum.codecrafters.io-topic-16007 Could not locate Gemfile