diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,18 @@
 
 ## Unreleased
 
+## [0.3.4] - 2019-10-01
+
+### Fixed
+
+- #240: push: prefer store paths as command arguments over stdin 
+
+  Some programming languages like go and nodejs always open
+  stdin pipe, which confuses cachix to think there's stdin content.
+  
+  Sadly checking stdin for contents is tricky since we get
+  into the whole buffering mess.
+
 ## [0.3.3] - 2019-09-25
 
 ### Fixed
@@ -128,6 +140,7 @@
 - Initial release @domenkozar
 
 [Unreleased]: https://github.com/cachix/cachix/compare/v0.3.0...HEAD
+[0.3.4]: https://github.com/cachix/cachix/compare/v0.3.3...v0.3.4
 [0.3.3]: https://github.com/cachix/cachix/compare/v0.3.2...v0.3.3
 [0.3.2]: https://github.com/cachix/cachix/compare/v0.3.1...v0.3.2
 [0.3.1]: https://github.com/cachix/cachix/compare/v0.3.0...v0.3.1
diff --git a/cachix.cabal b/cachix.cabal
--- a/cachix.cabal
+++ b/cachix.cabal
@@ -1,6 +1,6 @@
 cabal-version:      2.2
 name:               cachix
-version: 0.3.3
+version:            0.3.4
 license:            Apache-2.0
 license-file:       LICENSE
 copyright:          2018 Domen Kožar
diff --git a/src/Cachix/Client/Commands.hs b/src/Cachix/Client/Commands.hs
--- a/src/Cachix/Client/Commands.hs
+++ b/src/Cachix/Client/Commands.hs
@@ -150,17 +150,20 @@
       addBinaryCache (config env) binaryCache useOptions
         $ fromMaybe (getInstallationMode nixEnv) (useMode useOptions)
 
--- TODO: lots of room for perfomance improvements
+-- TODO: lots of room for performance improvements
 push :: Env -> PushArguments -> IO ()
-push env (PushPaths opts name rawPaths) = do
-  hasNoStdin <- hIsTerminalDevice stdin
-  when (not hasNoStdin && not (null rawPaths)) $ throwIO $ AmbiguousInput "You provided both stdin and store path arguments, pick only one to proceed."
+push env (PushPaths opts name cliPaths) = do
+  hasStdin <- not <$> hIsTerminalDevice stdin
   inputStorePaths <-
-    if hasNoStdin
-      then return rawPaths
-      else T.words <$> getContents
-  -- TODO: if empty, take whole nix store and warn: nix store-path --all
-  when (null inputStorePaths) $ throwIO $ NoInput "You need to specify store paths either as stdin or as a cli argument"
+    case (hasStdin, cliPaths) of
+      (False, []) -> throwIO $ NoInput "You need to specify store paths either as stdin or as an command argument"
+      (True, []) -> T.words <$> getContents
+      -- If we get both stdin and cli args, prefer cli args.
+      -- This avoids hangs in cases where stdin is non-interactive but unused by caller
+      -- some programming environments always create a (non-interactive) stdin
+      -- that may or may not be written to by the caller.
+      -- This is somewhat like the behavior of `cat` for example.
+      (_, paths) -> return paths
   sk <- findSigningKey env name
   store <- wait (storeAsync env)
   void
