Function works when called in Pluto, but not when copy-pasted into a package

It’s going to take a while to extract a MWE from the package and pluto notebook, so I’ll post the question first in case I get lucky. Note that I am self-taught and relatively new to Julia, so my code is probably bad.

I’m writing a package for data analysis, part of which is using helium pycnometry to determine sample volume. Needing to get data analysis for an experiment done faster, I started with a Pluto notebook for a specific dataset and am working to make a general package using PlutoDevMacros and VSCodium to transfer functions from Pluto to the package. Every function except one copy/pasted easily.

The MethodError’s list of arguments matches the function call for the Pycnometry function (below). This worked fine in Pluto and is a direct copy-paste in the package. I get the same error message whether I call the function from Pluto or use a script in VSCodiuim.

As I read the error, It is an error calling the function and not a problem in the function. The arguments in parentheses match the keyword arguments I defined, but the arguments after that add an argument that I did not define or call: the true at the beginning I think the hexadecimal at the end relates to the MethodError and not the function call. I do not know where it comes from, and assume that addition means Julia can’t find a function with the correct arguments to call.

Does anyone know where those two arguments come from and what to do about it?

Note: I’ve deleted the actual dataframes from the output–it did not look like they would be readable. The warning is the output from my Catch statement.

 Warning: function AnalyzeCellInjections!: Analysis Failed: MethodError(Core.kwcall, ((dry = false, InjectionGas = "helium", MaxItr = 100, InitialGuess = 25 mL, LeakAnalysis = true), true, 4×6 DataFrame, 4×10 DataFrame, 5.36 mL), 0x0000000000009925)

Function AnalyzeCellInjections below, the call to Pycnometry function is in the Try Catch near the end, data is stored in a struct for later output, cell.SourceInjectionData is the 4x6 dataframe in the error, and cell.InjectionData is the 4x10 dataframe

function AnalyzeCellInjections!(Cells::OrderedDict{Symbol, CellDefinition}; Dry = true, Pycnometry = false, 
	ExpFactors::Union{Missing, Integer} = missing, MaxItr::Integer = 100, LeakAnalysis::Bool = false, 
	Delayed::Union{Missing, Dates.Period} = missing, InitialGuess = 25u"mL")

	for (key, cell) in pairs(Cells)
			@info "Processing " * string(cell.Description)
		if !cell.GasCell
			MatchSourceData!(Cells, key)
			FlagEquilibriumPeriods!(cell.Data, cell.Injections, :InjIn; EquilPeriod = cell.Param.EquilPeriod, Advance = cell.Param.IgnorePeriod, Delay = cell.Param.GCDelay, GasCell = cell.GasCell, Delayed = Delayed)

			if !ismissing(ExpFactors)	
				if ExpFactors == 2
					cell.ExpFactors = Get2ExpFactors(cell.Data, cell.Injections, ValidInj = cell.Param.ValidInj)
				elseif ExpFactors == 1
					cell.ExpFactors = Get1ExpFactors(cell.Data, cell.Injections, ValidInj = cell.Param.ValidInj)
				elseif ExpFactors == 0
					cell.ExpFactors = GetLines(cell.Data, cell.Injections, ValidInj = cell.Param.ValidInj)
				else
					@warn "function AnalyzeCellInjections!: Invalid number of exponentials specified"
				end
			end
			cell.InjectionData = GetInjectionData(cell.Data, cell.Injections, :InjIn, σₙ = Cells[cell.GasKey].σₙ, ExpFactors = cell.ExpFactors, GasCell = cell.GasCell, Delayed = ismissing(Delayed) ? false : true)
			try
				if Pycnometry
					cell.Volume, cell.AdjVolume, cell.CombinedData = Pycnometry(cell.SourceInjectionData, cell.InjectionData, 
						Cells[cell.GasKey].Volume; dry = Dry, InjectionGas = Cells[cell.GasKey].InjectionGas, MaxItr = MaxItr, 
						InitialGuess = InitialGuess, LeakAnalysis = LeakAnalysis
					)
				else
					cell.CombinedData = InjectionAnalyis(cell.SourceInjectionData, cell.InjectionData; InjectionGas = Cells[cell.GasKey].InjectionGas, SampleMass = cell.SampleMass, RamanDissolvedConc = cell.RamanDissolvedConc, WaterMass = cell.WaterMass, HeadSpaceVolume = cell.Volume, GasCellVolume = Cells[cell.GasKey].Volume, MolesHe = cell.MolesHe)
				end
			catch error
				@warn "function AnalyzeCellInjections!: Analysis Failed: " * string(error)
				@debug string(key) * " Injection Data"
				@debug cell.InjectionData[:, 3:6]
				@debug string(cell.GasKey) * " Injection Data"
				@debug cell.SourceInjectionData[:, 3:6]
			end
		end
	end
	return nothing
end 

Pycnometry function

function Pycnometry(SourceInjectionData::DataFrame, TargetInjectionData::DataFrame, GasCellVolume::Quantities; 
    dry::Bool = true, InjectionGas::String = "helium", MaxItr::Integer = 100, InitialGuess::Quantities = 25u"ml", 
    LeakAnalysis::Bool = false)

	println("Pycnometry function called")

	InjectModel = SingleFluid(InjectionGas)
    HeN₂H₂O_GERG2008 = GERG2008(["helium", "nitrogen", "water"])
	
    #=
	drop uncertainty from measurements: Mole fractions must total 1.0 for Clapeyron (or use actual moles), 
    and the vector of mole fractions/moles does not work with the @uncertain macro to get uncertainties from 
    incompatible functions
    =#
	zForH2Ocalc = 1

	Tₒ = Measurements.value(TargetInjectionData.TargetTempBef[1])
	Pₒ = Measurements.value(TargetInjectionData.TargetPressBef[1])
	PP_H2O = PH2O(Tₒ) |> u"psi"

	if dry
		PP_H2O = 0u"psi"
		PP_N2 = Pₒ
		MF_H2O = PP_H2O / Pₒ
		MF_N2 = PP_N2 / Pₒ
		MF_He = 0 # not yet injected
		GasMixPre = [MF_He, MF_N2, MF_H2O]
	elseif Pₒ >= PP_H2O
		PP_N2 = Pₒ - PP_H2O
		MF_H2O = PP_H2O / Pₒ
		MF_N2 = PP_N2 / Pₒ
		MF_He = 0 # not yet injected
		GasMixPre = [MF_He, MF_N2, MF_H2O]
	else
		PP_N2 = 0u"psi"
		MF_H2O = 1
		MF_N2 = 0
		MF_He = 0 # not yet injected
		GasMixPre = [MF_He, MF_N2, MF_H2O] #assume entire pressure is water vapor
	end

	CombinedData = DataFrame()
	
	z = zFac(HeN₂H₂O_GERG2008, TargetInjectionData.TargetPressBef[1], TargetInjectionData.TargetTempBef[1], GasMixPre)
	TotalMolesBefore = MolesPresent(TargetInjectionData.TargetPressBef[1], TargetInjectionData.TargetTempBef[1], z, 
        InitialGuess
    ) |> u"mmol"

	CurrentVolume = InitialGuess
	PrevVolume = 0.0u"mL"
	if LeakAnalysis
		AdjCurrentVolume = InitialGuess
		AdjPrevVolume = 0.0u"mL"
		TotalMolesGasLeaked = zeros(nrow(TargetInjectionData)) .* u"mmol"
	else
		AdjCurrentVolume = InitialGuess
		AdjPrevVolume = InitialGuess
	end
	i = 0 # infinite loop break counter
	while (abs(PrevVolume - CurrentVolume) > 1e-10u"mL") || (abs(AdjPrevVolume - AdjCurrentVolume) > 1e-10u"mL")
		CombinedData = innerjoin(SourceInjectionData, TargetInjectionData, on = :Injection)
		PrevVolume = CurrentVolume
		AdjPrevVolume = AdjCurrentVolume
		@transform! CombinedData @astable begin
			:PSatH2O = dry ? (0u"psi" .* ones(nrow(CombinedData))) : PSat_H2Ounc.(:TargetTempAft)
			:MolesH2O = MolesPresent.(:PSatH2O, :TargetTempAft, zForH2Ocalc, CurrentVolume)
			:MolesN2BefPyc = TotalMolesBefore * MF_N2 .* ones(nrow(CombinedData))
			:zSourceBef = zFac.(InjectModel, :SourcePressBef, :SourceTempBef)
			:zSourceAft = zFac.(InjectModel, :SourcePressAft, :SourceTempAft)
			:SourceMolesGasBef = MolesPresent.(:SourcePressBef, :SourceTempBef, :zSourceBef, GasCellVolume) .|> u"mmol"
			:SourceMolesGasAft = MolesPresent.(:SourcePressAft, :SourceTempAft, :zSourceAft, GasCellVolume) .|> u"mmol"
			:MolesGasInjected = :SourceMolesGasBef - :SourceMolesGasAft .|> u"mmol"
			:TotalMolesGasInjected = cumsum(:MolesGasInjected) .|> u"mmol"
			:TotalMolesGasBefInj = :TotalMolesGasInjected - :MolesGasInjected
		end


		CombinedData.zTargetBef .= 1.0
		CombinedData.zTargetAft .= 1.0
		CombinedData.Volume .= (0.0±0.0)u"mL"
		if LeakAnalysis
			CombinedData.zAdjTargetAft .= 1.0
			CombinedData.AdjVolume .= (0.0±0.0)u"mL"
		end

		for (i, row) in enumerate(eachrow(CombinedData))
			if InjectionGas == "nitrogen"
				GasMixBef = Measurements.value.([0u"mmol", row.MolesN2BefPyc + row.TotalMolesGasBefInj, row.MolesH2O])
				GasMixAft = Measurements.value.([0u"mmol", row.MolesN2BefPyc + row.TotalMolesGasInjected, row.MolesH2O]) 
			else
				GasMixBef = Measurements.value.([row.TotalMolesGasBefInj, row.MolesN2BefPyc, row.MolesH2O])
				GasMixAft = Measurements.value.([row.TotalMolesGasInjected, row.MolesN2BefPyc, row.MolesH2O])
			end

			CombinedData.zTargetBef[i] = compressibility_factor(HeN₂H₂O_GERG2008, Measurements.value(row.TargetPressBef), 
                Measurements.value(row.TargetTempBef), GasMixBef
            )
			CombinedData.zTargetAft[i] = compressibility_factor(HeN₂H₂O_GERG2008, Measurements.value(row.TargetPressAft), 
                Measurements.value(row.TargetTempAft), GasMixAft
            )
			CombinedData.Volume[i] = PycVolume.(row.TargetPressAft, row.TargetTempAft, row.zTargetAft,  
                (row.MolesN2BefPyc + row.MolesH2O + row.TotalMolesGasInjected)
            )
		end

		if LeakAnalysis

			#need adj moles h20 and n2
			for (i, row) in enumerate(eachrow(CombinedData))					
				if InjectionGas == "nitrogen"
					AdjGasMixAft = Measurements.value.([0u"mmol", row.MolesN2BefPyc + row.TotalMolesGasInjected - 
                    TotalMolesGasLeaked[i], row.MolesH2O]
                    ) 
				else
					AdjGasMixAft = Measurements.value.([row.TotalMolesGasInjected - TotalMolesGasLeaked[i], 
                    row.MolesN2BefPyc, row.MolesH2O]
                    )
				end
				CombinedData.zAdjTargetAft[i] = compressibility_factor(HeN₂H₂O_GERG2008, 
                    Measurements.value(row.LeakRateAdjPressureAft), Measurements.value(row.TargetTempAft), AdjGasMixAft
                )
			end
			@transform! CombinedData @astable begin
				:MolesGasLeaked = MolesPresent.(:LeakRateAdjPressureAft, :TargetTempAft, :zAdjTargetAft, 
                    AdjCurrentVolume) - MolesPresent.(:TargetPressAft, :TargetTempAft, :zTargetAft, AdjCurrentVolume
                )
				:TotalMolesGasLeaked = cumsum(:MolesGasLeaked)
				:RemainingMolesGas = :TotalMolesGasInjected - :TotalMolesGasLeaked
				:InitialMolesGas = :RemainingMolesGas + :MolesGasLeaked
				:AdjVolume = PycVolume.(:LeakRateAdjPressureAft, :TargetTempAft, :zAdjTargetAft, :RemainingMolesGas)
			end
		end

		zForH2Ocalc = CombinedData.zTargetAft
		givenunit = unit(mean(CombinedData.Volume))
		CurrentVolume = weightedmean(ustrip.(CombinedData.Volume)) * givenunit
		if LeakAnalysis
			Adjgivenunit = unit(mean(CombinedData.AdjVolume))
			AdjCurrentVolume = weightedmean(ustrip.(CombinedData.AdjVolume)) * Adjgivenunit
			TotalMolesGasLeaked = CombinedData.TotalMolesGasLeaked
		end
		TotalMolesBefore = MolesPresent(CombinedData.TargetPressBef[1], CombinedData.TargetTempBef[1], 
            CombinedData.zTargetBef[1], CurrentVolume
        ) |> u"mmol"
		i += 1
		if i >= MaxItr
			@warn "Maximum Iterations reached"
			break
		end
	end
	@debug "Iterations: " * string(i)

    # weightedmean function gives the weighted mean of a set of measurements using inverses of variances as weights
	# weightedmean function is not compatible with units, get the given unit, strip it from the vector, 
    # calculate weighted mean and add the unit back
	givenunit = unit(mean(CombinedData.Volume)) #using the mean will cause errors if the units do not match
	TargetVolume = weightedmean(ustrip.(CombinedData.Volume)) * givenunit
	if LeakAnalysis
		Adjgivenunit = unit(mean(CombinedData.AdjVolume)) #using the mean will cause errors if the units do not match
		AdjTargetVolume = weightedmean(ustrip.(CombinedData.AdjVolume)) * Adjgivenunit
	else
		AdjTargetVolume = missing
	end
	return TargetVolume, AdjTargetVolume, CombinedData
end

By default, Pluto maintains its own environment using an embedded Project.toml/Manifest.toml separate from the global and project environments. If they are not on all fours with the package environment you are posting into, you would see this for any function that had a private dependency.